Merge valid_item functions
[platform/core/multimedia/media-server.git] / src / scanner-v2 / media-scanner-scan-v2.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 <malloc.h>
23
24 #include "media-util.h"
25 #include "media-server-ipc.h"
26 #include "media-common-utils.h"
27 #include "media-common-external-storage.h"
28 #include "media-common-db-svc.h"
29 #include "media-scanner-dbg-v2.h"
30 #include "media-scanner-common-v2.h"
31 #include "media-scanner-socket-v2.h"
32 #include "media-scanner-scan-v2.h"
33 #include "media-scanner-extract-v2.h"
34 #include "media-scanner-db-manage-v2.h"
35
36 #define MAX_SCAN_COUNT 300
37
38 #define DIR_SCAN_NON_SCAN               0
39 #define DIR_SCAN_RECURSIVE              1
40 #define DIR_SCAN_NON_RECURSIVE  2
41
42 #define RECYCLE_DIR_NAME        "$RECYCLE.BIN"
43
44
45 GAsyncQueue *storage_queue2;
46 static GAsyncQueue *scan_queue2;
47 static GAsyncQueue *reg_queue2;
48 static GMutex scan_req_mutex2;
49 static GMutex blocked_mutex2;
50 static GMutex storage_scan_mutex2;
51 static GMutex dir_scan_mutex2;
52 static GCond data_cond2;        /* Must be initialized somewhere */
53 static GMutex data_mutex2;      /* Must be initialized somewhere */
54 static GMutex scan_item_mutex;
55
56 static char *g_blocked_path2;
57
58 static s_scan_item* cancel_scan_item = NULL;
59 static s_scan_item* cur_scan_item = NULL;
60
61 int g_directory_scan_processing2 = DIR_SCAN_NON_SCAN;
62 static char *g_storage_scan_path;
63 static char* g_dir_scan_path;
64 static bool is_scanner_paused = false;
65
66 static int __msc_check_stop_status(int scan_type, const char *start_path, int pid);
67 static int __msc_get_null_scan_folder_list(sqlite3 *handle, const char *stroage_id, char *path, GPtrArray *dir_array);
68 static int __msc_check_scan_same_path(char *scan_path);
69 static void __msc_set_storage_scan_cur_path(char *scan_path);
70 static void __msc_set_dir_scan_cur_path(char *scan_path);
71 static int __msc_dir_and_storage_scan_same_path(char *start_path);
72 static int __msc_check_memory_status(uid_t uid);
73 static int __msc_check_remain_space(uid_t uid);
74 static void __msc_del_blocked_path(void);
75
76 void msc_init_scan_thread(void)
77 {
78         g_mutex_init(&data_mutex2);
79         g_mutex_init(&blocked_mutex2);
80         g_mutex_init(&scan_req_mutex2);
81         g_mutex_init(&storage_scan_mutex2);
82         g_mutex_init(&dir_scan_mutex2);
83         g_mutex_init(&scan_item_mutex);
84
85         g_cond_init(&data_cond2);
86 }
87
88 void msc_deinit_scan_thread(void)
89 {
90         g_mutex_clear(&data_mutex2);
91         g_mutex_clear(&blocked_mutex2);
92         g_mutex_clear(&scan_req_mutex2);
93         g_mutex_clear(&storage_scan_mutex2);
94         g_mutex_clear(&dir_scan_mutex2);
95         g_mutex_clear(&scan_item_mutex);
96
97         g_cond_clear(&data_cond2);
98 }
99
100 static void __msc_resume_scan(void)
101 {
102         g_mutex_lock(&data_mutex2);
103
104         if (is_scanner_paused) {
105                 is_scanner_paused = false;
106                 g_cond_signal(&data_cond2);
107                 MS_DBG_WARN("storage scan resumed");
108         }
109
110         g_mutex_unlock(&data_mutex2);
111 }
112
113 static void __msc_pause_scan(void)
114 {
115         g_mutex_lock(&data_mutex2);
116
117         if (!is_scanner_paused) {
118                 is_scanner_paused = true;
119                 MS_DBG_WARN("storage scan paused");
120
121                 while (is_scanner_paused)
122                         g_cond_wait(&data_cond2, &data_mutex2);
123         }
124
125         g_mutex_unlock(&data_mutex2);
126 }
127
128 static int __msc_check_stop_status(int scan_type, const char *start_path, int pid)
129 {
130         int ret = MS_MEDIA_ERR_NONE;
131
132         /*check poweroff status*/
133         if (_msc_is_power_off())
134                 return MS_MEDIA_ERR_SCANNER_FORCE_STOP;
135
136         if (scan_type == MS_MSG_DIRECTORY_SCANNING || scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
137                 g_mutex_lock(&scan_req_mutex2);
138                 /* check cancel path */
139                 //MS_DBG_ERR("__msc_check_stop_status...");
140                 if ((cancel_scan_item != NULL) && (cancel_scan_item->path != NULL)) {
141                         MS_DBG_SWARN("check blocked storage [%s][%s]", cancel_scan_item->path, start_path);
142                         if ((strncmp(cancel_scan_item->path, start_path, strlen(cancel_scan_item->path)) == 0)
143                                 && (cancel_scan_item->pid == -1 || cancel_scan_item->pid == pid)) {
144                                 MS_DBG_SWARN("Receive cancel request [%s][%s]. STOP scan!!", cancel_scan_item->path, start_path);
145                                 unsigned int path_len = strlen(cancel_scan_item->path);
146
147                                 if (strlen(start_path) > path_len) {
148                                         if (start_path[path_len] == '/') {
149                                                 MS_DBG_ERR("start path is same as cancel path");
150                                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
151                                         } else {
152                                                 MS_DBG_ERR("start path is not same as cancel path");
153                                         }
154                                 } else {
155                                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
156                                 }
157                         }
158                 }
159
160                 g_mutex_unlock(&scan_req_mutex2);
161         }
162
163         if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
164                 g_mutex_lock(&blocked_mutex2);
165                 /* check cancel path */
166                 if (g_blocked_path2 != NULL) {
167                         MS_DBG_SWARN("check blocked storage [%s][%s]", g_blocked_path2, start_path);
168                         if (strncmp(start_path, g_blocked_path2, strlen(start_path)) == 0) {
169                                 MS_DBG_ERR("Receive blocked message[%s][%s]. STOP scan!!",
170                                 g_blocked_path2, start_path);
171                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
172                         }
173
174                         MS_SAFE_FREE(g_blocked_path2);
175                 }
176
177                 g_mutex_unlock(&blocked_mutex2);
178         }
179
180         return ret;
181 }
182
183 static int __msc_dir_scan_for_folder(sqlite3 *handle, const char *storage_id, char *start_path, int scan_type, int pid, uid_t uid)
184 {
185         GPtrArray *dir_array = NULL;
186         int ret = MS_MEDIA_ERR_NONE;
187         char *new_path = NULL;
188         char *current_path = NULL;
189         char path[MS_FILE_PATH_LEN_MAX] = {0, };
190         bool is_recursive = (scan_type == MS_MSG_DIRECTORY_SCANNING);
191         char *new_start_path = NULL;
192
193         int scan_count = 0;
194         int sleep_count = 0;
195
196         GDir *dir = NULL;
197         GError *error = NULL;
198         const char *name;
199
200         MS_DBG_SWARN("storage id [%s] start path [%s]", storage_id, start_path);
201
202         new_start_path = g_strdup(start_path);
203
204         dir_array = g_ptr_array_new();
205         g_ptr_array_add(dir_array, start_path);
206
207         if (g_file_test(new_start_path, G_FILE_TEST_IS_DIR)) {
208                 if (ms_insert_folder(handle, storage_id, new_start_path, uid) != MS_MEDIA_ERR_NONE)
209                         MS_DBG_ERR("insert folder failed");
210
211                 MS_DBG_SWARN("ms_insert_folder insert path[%s]", new_start_path);
212         } else {
213                 if (ms_set_folder_validity(handle, storage_id, new_start_path, MS_INVALID, is_recursive, uid) != MS_MEDIA_ERR_NONE)
214                         MS_DBG_ERR("set_folder_validity failed [%d] ", scan_type);
215         }
216
217         while (dir_array->len != 0) {
218                 ret = __msc_check_stop_status(scan_type, new_start_path, pid);
219                 if (ret != MS_MEDIA_ERR_NONE) {
220                         if (is_recursive)
221                                 ms_change_validity_item_batch(handle, storage_id, new_start_path, 1, 2, uid);
222
223                         goto STOP_SCAN;
224                 }
225
226                 ms_register_end(uid);
227                 ms_register_start(false, 0);
228
229                 current_path = g_ptr_array_index(dir_array, 0);
230                 g_ptr_array_remove_index(dir_array, 0);
231
232                 __msc_set_dir_scan_cur_path(current_path);
233
234                 ret = ms_check_scan_ignore(current_path, uid);
235                 if (ret != MS_MEDIA_ERR_NONE) {
236                         MS_DBG_SERR("%s is ignore", current_path);
237                         MS_SAFE_FREE(current_path);
238                         if (ret == MS_MEDIA_ERR_USB_UNMOUNTED)
239                                 goto STOP_SCAN;
240
241                         ret = MS_MEDIA_ERR_NONE;
242                         continue;
243                 }
244
245                 ret = msc_check_db_size(uid, scan_type);
246                 if (ret != MS_MEDIA_ERR_NONE) {
247                         if (ret == MS_MEDIA_ERR_DB_FULL_FAIL)
248                                 ret = MS_MEDIA_ERR_NONE;
249
250                         if (is_recursive)
251                                 ms_change_validity_item_batch(handle, storage_id, new_start_path, 1, 2, uid);
252
253                         goto STOP_SCAN;
254                 }
255
256                 ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_PROCESSING, uid);
257                 sleep_count = 0;
258
259                 dir = g_dir_open(current_path, 0, &error);
260                 if (error != NULL) {
261                         MS_DBG_ERR("g_dir_open fails [%s]", current_path);
262                         MS_SAFE_FREE(current_path);
263                         g_error_free(error);
264                         error = NULL;
265                         continue;
266                 }
267
268                 while ((name = g_dir_read_name(dir))) {
269                         sleep_count++;
270                         if (sleep_count % 5 == 0) {
271                                 sleep_count = 0;
272                                 usleep(SCAN_SLEEP_TIME);
273                         }
274
275                         ret = __msc_check_stop_status(scan_type, new_start_path, pid);
276                         if (ret != MS_MEDIA_ERR_NONE) {
277                                 if (is_recursive)
278                                         ms_change_validity_item_batch(handle, storage_id, new_start_path, 1, 2, uid);
279
280                                 goto STOP_SCAN;
281                         }
282
283                         ret = msc_check_db_size(uid, scan_type);
284                         if (ret != MS_MEDIA_ERR_NONE) {
285                                 if (ret == MS_MEDIA_ERR_DB_FULL_FAIL)
286                                         ret = MS_MEDIA_ERR_NONE;
287
288                                 if (is_recursive)
289                                         ms_change_validity_item_batch(handle, storage_id, new_start_path, 1, 2, uid);
290
291                                 goto STOP_SCAN;
292                         }
293
294                         if (name[0] == '.')
295                                 continue;
296
297                         if (strcmp(name, RECYCLE_DIR_NAME) == 0)
298                                 continue;
299
300                         if (g_snprintf(path, MS_FILE_PATH_LEN_MAX, "%s/%s", current_path, name) >= MS_FILE_PATH_LEN_MAX) {
301                                 MS_DBG_ERR("g_snprintf failed");
302                                 continue;
303                         }
304
305                         if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
306                                 if (!ms_check_support_media_type(path))
307                                         continue;
308
309                                 ret = ms_validate_item(handle, storage_id, path, uid);
310                                 if (ret != MS_MEDIA_ERR_NONE) {
311                                         MS_DBG_ERR("failed to update db : %d", ret);
312                                         continue;
313                                 } else {
314                                         ++scan_count;
315
316                                         if (scan_count >= MAX_SCAN_COUNT) {
317                                                 scan_count = 0;
318
319                                                 ret = __msc_check_stop_status(scan_type, new_start_path, pid);
320                                                 if (ret == MS_MEDIA_ERR_NONE) {
321                                                         msc_insert_exactor_request(scan_type, false, storage_id, current_path, pid, uid, MS_ITEM_UPDATE);
322                                                 } else {
323                                                         if (is_recursive)
324                                                                 ms_change_validity_item_batch(handle, storage_id, new_start_path, 1, 2, uid);
325                                                         goto STOP_SCAN;
326                                                 }
327                                         }
328                                 }
329                         } else {
330                                 if (scan_type == MS_MSG_DIRECTORY_SCANNING) {
331                                         new_path = g_strdup(path);
332                                         g_ptr_array_add(dir_array, new_path);
333
334                                         if (ms_insert_folder(handle, storage_id, new_path, uid) != MS_MEDIA_ERR_NONE)
335                                                 MS_DBG_ERR("insert folder failed");
336
337                                 } else {
338                                         if (ms_insert_folder(handle, storage_id, path, uid) != MS_MEDIA_ERR_NONE) {
339                                                 MS_DBG_ERR("insert folder failed");
340                                                 continue;
341                                         }
342                                 }
343                         }
344                 }
345                 if (scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE)
346                         ms_update_folder_time(handle, storage_id, current_path, uid);
347
348                 ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_DONE, uid);
349
350                 MS_SAFE_FREE(current_path);
351
352                 if (dir) {
353                         g_dir_close(dir);
354                         dir = NULL;
355                 }
356
357                 __msc_set_dir_scan_cur_path(NULL);
358                 usleep(SCAN_SLEEP_TIME);
359         }
360
361         goto END_SCAN;
362
363 STOP_SCAN:
364         MS_DBG_ERR("stop folder scan...");
365         ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_STOP, uid);
366         MS_SAFE_FREE(current_path);
367
368 END_SCAN:
369         if (dir) {
370                 g_dir_close(dir);
371                 dir = NULL;
372         }
373
374         g_free(new_start_path);
375         __msc_set_dir_scan_cur_path(NULL);
376
377         g_ptr_array_free(dir_array, TRUE);
378
379         ms_register_end(uid);
380
381         if (ret != MS_MEDIA_ERR_NONE)
382                 MS_DBG_INFO("ret : %d", ret);
383
384         return ret;
385 }
386
387 static int __msc_dir_scan_for_storage(sqlite3 *handle, const char *storage_id, char *start_path, int scan_type, int pid, uid_t uid)
388 {
389         GPtrArray *dir_array = NULL;
390         int ret = MS_MEDIA_ERR_NONE;
391         char *new_path = NULL;
392         char *current_path = NULL;
393         char path[MS_FILE_PATH_LEN_MAX] = {0, };
394         int (*scan_function)(sqlite3 *, const char*, const char*, uid_t) = NULL;
395         char *new_start_path = NULL;
396
397         int scan_count = 0;
398         int sleep_count = 0;
399
400         GDir *dir = NULL;
401         GError *error = NULL;
402         const char *name;
403
404         bool is_missing = false;
405         ms_dir_scan_status_e scan_status = MS_DIR_SCAN_NONE;
406
407         MS_DBG_SWARN("storage id [%s] start path [%s]", storage_id, start_path);
408
409         new_start_path = g_strdup(start_path);
410
411         dir_array = g_ptr_array_new();
412         g_ptr_array_add(dir_array, start_path);
413
414         if (ms_insert_folder(handle, storage_id, new_start_path, uid) != MS_MEDIA_ERR_NONE)
415                 MS_DBG_ERR("insert folder failed");
416
417         scan_function = (scan_type == MS_MSG_STORAGE_ALL) ? ms_scan_item_batch : ms_validate_item;
418
419         ms_register_end(uid);
420
421         while (dir_array->len != 0) {
422                 ret = __msc_check_stop_status(scan_type, new_start_path, pid);
423                 if (ret != MS_MEDIA_ERR_NONE)
424                         goto STOP_SCAN;
425
426                 ms_register_start(false, 0);
427
428                 current_path = g_ptr_array_index(dir_array, 0);
429                 g_ptr_array_remove_index(dir_array, 0);
430
431                 __msc_set_storage_scan_cur_path(current_path);
432
433                 ret = ms_check_scan_ignore(current_path, uid);
434                 if (ret != MS_MEDIA_ERR_NONE) {
435                         MS_DBG_SERR("%s is ignore", current_path);
436                         MS_SAFE_FREE(current_path);
437                         if (ret == MS_MEDIA_ERR_USB_UNMOUNTED)
438                                 goto STOP_SCAN;
439
440                         ret = MS_MEDIA_ERR_NONE;
441                         continue;
442                 }
443
444                 ret = msc_check_db_size(uid, scan_type);
445                 if (ret != MS_MEDIA_ERR_NONE)
446                         goto STOP_SCAN;
447
448                 ms_get_folder_scan_status(handle, storage_id, current_path, (int *)&scan_status);
449
450                 if (scan_status == MS_DIR_SCAN_PROCESSING && g_directory_scan_processing2 != DIR_SCAN_NON_SCAN) {
451
452                         MS_DBG_SERR("%s is scanning, ignore current path, scan next path !!", current_path);
453
454                         is_missing = true;
455                         goto NEXT_SCAN;
456
457                 } else if (scan_status == MS_DIR_SCAN_DONE) {
458                         if (g_directory_scan_processing2 == DIR_SCAN_NON_RECURSIVE) {
459                                 MS_DBG_SERR("%s is scan done, ignore current path, get subfolder list!!", current_path);
460
461                                 __msc_get_null_scan_folder_list(handle, storage_id, current_path, dir_array);
462
463                                 continue;
464
465                         } else if (g_directory_scan_processing2 == DIR_SCAN_RECURSIVE) {
466                                 MS_DBG_SERR("%s is scan done, ignore current path, scan next path!!", current_path);
467
468                                 is_missing = true;
469                                 goto NEXT_SCAN;
470                         }
471                 }
472
473                 ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_PROCESSING, uid);
474                 sleep_count = 0;
475
476                 dir = g_dir_open(current_path, 0, &error);
477                 if (error != NULL) {
478                         MS_DBG_ERR("g_dir_open fails [%s]", current_path);
479                         MS_SAFE_FREE(current_path);
480                         g_error_free(error);
481                         error = NULL;
482                         continue;
483                 }
484
485                 while ((name = g_dir_read_name(dir))) {
486                         sleep_count++;
487                         if (sleep_count % 5 == 0) {
488                                 sleep_count = 0;
489                                 usleep(SCAN_SLEEP_TIME);
490                         }
491
492                         ret = __msc_check_stop_status(scan_type, new_start_path, pid);
493                         if (ret != MS_MEDIA_ERR_NONE)
494                                 goto STOP_SCAN;
495
496                         ret = msc_check_db_size(uid, scan_type);
497                         if (ret != MS_MEDIA_ERR_NONE)
498                                 goto STOP_SCAN;
499
500                         if (name[0] == '.')
501                                 continue;
502
503                         if (strcmp(name, RECYCLE_DIR_NAME) == 0)
504                                 continue;
505
506                         if (g_snprintf(path, MS_FILE_PATH_LEN_MAX, "%s/%s", current_path, name) >= MS_FILE_PATH_LEN_MAX) {
507                                 MS_DBG_ERR("g_snprintf failed");
508                                 continue;
509                         }
510
511                         if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
512                                 if (!ms_check_support_media_type(path))
513                                         continue;
514
515                                 ret = scan_function(handle, storage_id, path, uid);
516                                 if (ret != MS_MEDIA_ERR_NONE) {
517                                         MS_DBG_ERR("failed to update db : %d", scan_type);
518                                         continue;
519                                 } else {
520                                         ++scan_count;
521                                         if (scan_count >= MAX_SCAN_COUNT) {
522                                                 scan_count = 0;
523                                                 msc_insert_exactor_request(scan_type, false, storage_id, current_path, 0, uid, MS_ITEM_UPDATE);
524                                         }
525                                 }
526                         } else {
527                                 new_path = g_strdup(path);
528                                 g_ptr_array_add(dir_array, new_path);
529
530                                 if (ms_insert_folder(handle, storage_id, new_path, uid) != MS_MEDIA_ERR_NONE)
531                                         MS_DBG_ERR("insert folder failed");
532                         }
533                 }
534
535                 ms_register_end(uid);
536                 ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_DONE, uid);
537
538                 if (dir) {
539                         g_dir_close(dir);
540                         dir = NULL;
541                 }
542
543 NEXT_SCAN:
544                 MS_SAFE_FREE(current_path);
545                 __msc_set_storage_scan_cur_path(NULL);
546
547                 if (dir_array->len == 0 && is_missing) {
548                         is_missing = false;
549
550                         if (g_directory_scan_processing2 == DIR_SCAN_NON_SCAN) {
551                                 ret = __msc_get_null_scan_folder_list(handle, storage_id, NULL, dir_array);
552
553                                 MS_DBG_WARN("no wait folder scan callback");
554
555                                 if (ret != MS_MEDIA_ERR_NONE)
556                                         break;
557                         } else {
558                                 __msc_pause_scan();
559
560                                 ret = __msc_get_null_scan_folder_list(handle, storage_id, NULL, dir_array);
561
562                                 if (ret != MS_MEDIA_ERR_NONE)
563                                         break;
564                         }
565                 }
566                 usleep(SCAN_SLEEP_TIME);
567         }
568
569         if (!MS_STRING_VALID(MEDIA_ROOT_PATH_USB)) {
570                 MS_DBG_ERR("Fail to get USB path");
571                 goto END_SCAN;
572         }
573
574         if (strstr(new_start_path, MEDIA_ROOT_PATH_USB) != NULL) {
575                 if (!ms_storage_mount_status(new_start_path)) {
576                         MS_DBG_ERR("start path is unmounted");
577                         goto END_SCAN;
578                 }
579         }
580
581         if ((g_directory_scan_processing2 != DIR_SCAN_NON_SCAN)
582                 && (__msc_dir_and_storage_scan_same_path(new_start_path) == MS_MEDIA_ERR_NONE))
583                 __msc_pause_scan();
584
585         goto END_SCAN;
586
587 STOP_SCAN:
588         if (current_path != NULL)
589                 ms_set_folder_scan_status(handle, storage_id, current_path, MS_DIR_SCAN_STOP, uid);
590         MS_SAFE_FREE(current_path);
591
592 END_SCAN:
593         if (dir) {
594                 g_dir_close(dir);
595                 dir = NULL;
596         }
597
598         g_free(new_start_path);
599         __msc_set_storage_scan_cur_path(NULL);
600         g_ptr_array_free(dir_array, TRUE);
601
602         ms_register_end(uid);
603
604         if (ret != MS_MEDIA_ERR_NONE)
605                 MS_DBG_INFO("ret : %d", ret);
606
607         return ret;
608 }
609
610 static int __msc_get_null_scan_folder_list(sqlite3 *handle, const char *stroage_id, char *path, GPtrArray *dir_array)
611 {
612         int ret = MS_MEDIA_ERR_NONE;
613         GPtrArray *cur_dir_array = NULL;
614
615         ret = ms_get_null_scan_folder_list(handle, stroage_id, path, &cur_dir_array);
616         if (ret == MS_MEDIA_ERR_NONE) {
617                 MS_DBG_WARN("cur_dir_array->len = [%d]", cur_dir_array->len);
618                 g_ptr_array_extend_and_steal(dir_array, cur_dir_array);
619         }
620
621         return ret;
622 }
623
624 static int __msc_check_scan_same_path(char *scan_path)
625 {
626         int ret = MS_MEDIA_ERR_NONE;
627         unsigned int storage_len, folder_len, min_len;
628
629         g_mutex_lock(&storage_scan_mutex2);
630
631         if (NULL == scan_path || NULL == g_storage_scan_path) {
632                 g_mutex_unlock(&storage_scan_mutex2);
633
634                 return MS_MEDIA_ERR_INTERNAL;
635         }
636
637         storage_len = strlen(g_storage_scan_path);
638         folder_len = strlen(scan_path);
639         min_len = storage_len > folder_len ? folder_len : storage_len;
640
641         ret = strncmp(g_storage_scan_path, scan_path, min_len);
642
643         g_mutex_unlock(&storage_scan_mutex2);
644
645         return abs(ret);
646 }
647
648 static void __msc_set_storage_scan_cur_path(char *scan_path)
649 {
650         g_mutex_lock(&storage_scan_mutex2);
651
652         g_free(g_storage_scan_path);
653         g_storage_scan_path = g_strdup(scan_path);
654
655         g_mutex_unlock(&storage_scan_mutex2);
656 }
657
658 static int __msc_dir_and_storage_scan_same_path(char *start_path)
659 {
660         int ret = MS_MEDIA_ERR_NONE;
661         unsigned int storage_len, folder_len;
662
663         char *storage_path = NULL;
664         char *remain_path = NULL;
665         int remain_len = 0;
666
667         if (!MS_STRING_VALID(MEDIA_ROOT_PATH_USB)) {
668                 MS_DBG_ERR("Fail to get USB path");
669                 return MS_MEDIA_ERR_INTERNAL;
670         }
671
672         remain_path = strstr(start_path+strlen(MEDIA_ROOT_PATH_USB) +1, "/");
673         if (remain_path != NULL)
674                 remain_len = strlen(remain_path);
675
676         storage_path = g_strndup(start_path, strlen(start_path) - remain_len);
677
678         g_mutex_lock(&dir_scan_mutex2);
679
680         if (NULL == g_dir_scan_path || NULL == storage_path) {
681                 g_free(storage_path);
682                 g_mutex_unlock(&dir_scan_mutex2);
683
684                 return MS_MEDIA_ERR_INTERNAL;
685         }
686
687         storage_len = strlen(storage_path);
688         folder_len = strlen(g_dir_scan_path);
689
690         if (folder_len < storage_len)
691                 ret = -1;
692         else
693                 ret = strncmp(storage_path, g_dir_scan_path, storage_len);
694
695         g_free(storage_path);
696         g_mutex_unlock(&dir_scan_mutex2);
697
698         return abs(ret);
699 }
700
701
702 static void __msc_set_dir_scan_cur_path(char *scan_path)
703 {
704         g_mutex_lock(&dir_scan_mutex2);
705
706         g_free(g_dir_scan_path);
707         g_dir_scan_path = g_strdup(scan_path);
708
709         g_mutex_unlock(&dir_scan_mutex2);
710 }
711
712 static int __msc_db_update(sqlite3 *handle, const char *storage_id, const ms_comm_msg_s * scan_data)
713 {
714         int err = MS_MEDIA_ERR_NONE;
715         char *start_path = NULL;
716
717         if (scan_data->msg_type != MS_MSG_STORAGE_INVALID) {
718                 MS_DBG_WARN("INSERT");
719                 start_path = g_strdup(scan_data->msg);
720                 if (scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING || scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE)
721                         err = __msc_dir_scan_for_folder(handle, storage_id, start_path, scan_data->msg_type, scan_data->pid, scan_data->uid);
722                 else if (scan_data->msg_type == MS_MSG_STORAGE_ALL || scan_data->msg_type == MS_MSG_STORAGE_PARTIAL)
723                         err = __msc_dir_scan_for_storage(handle, storage_id, start_path, scan_data->msg_type, scan_data->pid, scan_data->uid);
724
725                 if (err != MS_MEDIA_ERR_NONE)
726                         MS_DBG_ERR("error : %d", err);
727
728         } else {
729                 MS_DBG_WARN("INVALID");
730                 msc_remove_extract_request(scan_data);
731         }
732
733         sync();
734
735         return err;
736 }
737
738 static int __msc_set_scan_item(s_scan_item **item, const char* path, int pid)
739 {
740         s_scan_item* scan_item = *item;
741
742         if (!scan_item)
743                 scan_item = g_new0(s_scan_item, 1);
744
745         g_free(scan_item->path);
746
747         scan_item->path = g_strdup(path);
748         scan_item->pid = pid;
749
750         *item = scan_item;
751
752         MS_DBG_SWARN("path[%s],pid[%d]", scan_item->path, scan_item->pid);
753
754         return MS_MEDIA_ERR_NONE;
755 }
756
757 static void __msc_del_cancel_scan_item(void)
758 {
759         g_mutex_lock(&scan_item_mutex);
760
761         if (cancel_scan_item) {
762                 g_free(cancel_scan_item->path);
763                 g_free(cancel_scan_item);
764                 cancel_scan_item = NULL;
765         }
766
767         g_mutex_unlock(&scan_item_mutex);
768 }
769
770 static void __msc_del_cur_scan_item(void)
771 {
772         g_mutex_lock(&scan_item_mutex);
773
774         if (cur_scan_item) {
775                 g_free(cur_scan_item->path);
776                 g_free(cur_scan_item);
777                 cur_scan_item = NULL;
778         }
779
780         g_mutex_unlock(&scan_item_mutex);
781 }
782
783 gpointer msc_directory_scan_thread(gpointer data)
784 {
785         ms_comm_msg_s *scan_data = NULL;
786         int ret = MS_MEDIA_ERR_NONE;
787         sqlite3 *handle = NULL;
788         bool modified = false;
789         ms_dir_scan_status_e scan_status = MS_DIR_SCAN_NONE;
790         ms_noti_type_e noti_type = MS_ITEM_INSERT;
791         char *folder_uuid = NULL;
792         bool is_recursive = true;
793
794         while (1) {
795                 scan_data = g_async_queue_pop(scan_queue2);
796                 ret = MS_MEDIA_ERR_NONE;
797
798                 if (scan_data->pid == POWEROFF) {
799                         MS_DBG_ERR("power off");
800                         goto _POWEROFF;
801                 }
802
803                 MS_DBG_WARN("DIRECTORY SCAN START [%.*s][%s][%d]", MAX_MSG_SIZE, scan_data->msg, scan_data->storage_id, scan_data->msg_type);
804
805                 if (strlen(scan_data->storage_id) == 0) {
806                         MS_DBG_ERR("storage_id length is 0");
807                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
808                         goto NEXT;
809                 }
810
811                 if (scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING &&
812                         scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
813                         MS_DBG_ERR("Invalid request");
814                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
815                         goto NEXT;
816                 }
817
818                 ret = ms_connect_db(&handle, scan_data->uid);
819                 if (ret != MS_MEDIA_ERR_NONE) {
820                         MS_DBG_ERR("ms_connect_db failed");
821                         goto NEXT;
822                 }
823
824                 /*check remain space*/
825                 if (__msc_check_remain_space(scan_data->uid) != MS_MEDIA_ERR_NONE)
826                         goto SCAN_DONE;
827
828                 g_mutex_lock(&scan_item_mutex);
829                 __msc_set_scan_item(&cur_scan_item, scan_data->msg, scan_data->pid);
830                 g_mutex_unlock(&scan_item_mutex);
831
832                 g_directory_scan_processing2 = DIR_SCAN_NON_RECURSIVE;
833
834                 ms_trim_dir_path(scan_data->msg);
835
836                 if (g_file_test(scan_data->msg, G_FILE_TEST_IS_DIR)) {
837                         is_recursive = (scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING);
838                         if (ms_check_folder_exist(handle, scan_data->storage_id, scan_data->msg) == MS_MEDIA_ERR_NONE) {
839                                 noti_type = MS_ITEM_UPDATE;
840                                 MS_DBG_WARN("[%.*s] already exist", MAX_MSG_SIZE, scan_data->msg);
841                         } else {
842                                 noti_type = MS_ITEM_INSERT;
843                                 MS_DBG_WARN("[%.*s] new insert path", MAX_MSG_SIZE, scan_data->msg);
844                         }
845                 } else {
846                         is_recursive = true;
847                         noti_type = MS_ITEM_DELETE;
848                         scan_data->msg_type = MS_MSG_DIRECTORY_SCANNING;
849
850                         ms_get_folder_id(handle, scan_data->storage_id, scan_data->msg, &folder_uuid);
851
852                         MS_DBG_SWARN("[%.*s][%s] delete path", MAX_MSG_SIZE, scan_data->msg, folder_uuid);
853                 }
854
855                 if (scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING) {
856                         MS_DBG_WARN("start recursive dir scan!!");
857                         g_directory_scan_processing2 = DIR_SCAN_RECURSIVE;
858
859                         if (__msc_check_scan_same_path(scan_data->msg) == 0) {
860                                 MS_DBG_WARN("[%.*s] is scanning recursive, waiting...", MAX_MSG_SIZE, scan_data->msg);
861                                 msc_send_result_partial(ret, MS_MSG_RECURSIVE_START, scan_data->pid, scan_data->msg);
862
863                                 while (__msc_check_scan_same_path(scan_data->msg) == 0) {
864                                         sleep(1);
865
866                                         ret = __msc_check_stop_status(scan_data->msg_type, scan_data->msg, scan_data->pid);
867                                         if (ret != MS_MEDIA_ERR_NONE)
868                                                 goto NEXT;
869                                 }
870
871                                 MS_DBG_WARN("[%.*s] scan done, wait finished", MAX_MSG_SIZE, scan_data->msg);
872                                 goto SCAN_DONE;
873
874                         }
875
876                         ms_get_folder_scan_status(handle, scan_data->storage_id, scan_data->msg, (int*)&scan_status);
877
878                         if (scan_status == MS_DIR_SCAN_DONE)
879                                 ms_set_folder_item_validity(handle, scan_data->storage_id, scan_data->msg, MS_VALID_V2, MS_RECURSIVE, scan_data->uid);
880                         else
881                                 ms_set_folder_item_validity(handle, scan_data->storage_id, scan_data->msg, MS_INVALID, MS_RECURSIVE, scan_data->uid);
882
883                         msc_send_result_partial(ret, MS_MSG_RECURSIVE_START, scan_data->pid, scan_data->msg);
884                 } else {
885                         MS_DBG_WARN("start non recursive dir scan!!");
886
887                         g_directory_scan_processing2 = DIR_SCAN_NON_RECURSIVE;
888                         ms_check_folder_modified(handle, scan_data->msg, scan_data->storage_id, &modified);
889
890                         if (!modified) {
891                                 MS_DBG_WARN("check [%.*s] has not been modified !!", MAX_MSG_SIZE, scan_data->msg);
892                                 ms_get_folder_scan_status(handle, scan_data->storage_id, scan_data->msg, (int*)&scan_status);
893                                 MS_DBG_WARN("folder scan status = [%d]", scan_status);
894
895                                 if (scan_status == MS_DIR_SCAN_DONE) {
896                                         MS_DBG_WARN("[%.*s] scan done", MAX_MSG_SIZE, scan_data->msg);
897                                         goto SCAN_DONE;
898                                 } else if (scan_status == MS_DIR_SCAN_PROCESSING) {
899                                         MS_DBG_WARN("[%.*s] scanning, waiting...", MAX_MSG_SIZE, scan_data->msg);
900
901                                         while (1) {
902                                                 sleep(1);
903
904                                                 ret = __msc_check_stop_status(scan_data->msg_type, scan_data->msg, scan_data->pid);
905                                                 if (ret != MS_MEDIA_ERR_NONE)
906                                                         goto NEXT;
907
908
909                                                 ms_get_folder_scan_status(handle, scan_data->storage_id, scan_data->msg, (int*)&scan_status);
910                                                 if (scan_status == MS_DIR_SCAN_DONE) {
911                                                         MS_DBG_WARN("[%.*s] [MS_DIR_SCAN_DONE]", MAX_MSG_SIZE, scan_data->msg);
912                                                         goto SCAN_DONE;
913                                                 }
914
915                                                 if (scan_status == MS_DIR_SCAN_STOP) {
916                                                         MS_DBG_WARN("[%.*s] [MS_DIR_SCAN_STOP]", MAX_MSG_SIZE, scan_data->msg);
917                                                         break;
918                                                 }
919                                         }
920                                 }
921                         } else {
922                                 MS_DBG_WARN("check [%.*s] has been modified !!", MAX_MSG_SIZE, scan_data->msg);
923                         }
924
925                         ret = ms_set_folder_item_validity(handle, scan_data->storage_id, scan_data->msg, MS_INVALID, MS_NON_RECURSIVE, scan_data->uid);
926                         if (ret != MS_MEDIA_ERR_NONE)
927                                 MS_DBG_ERR("error : %d", ret);
928                 }
929
930                 ms_register_start(false, 0);
931
932                 ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
933
934                 ms_register_end(scan_data->uid);
935
936                 MS_DBG_WARN("folder scan done, sent cb event path = [%.*s]", MAX_MSG_SIZE, scan_data->msg);
937
938                 __msc_resume_scan();
939
940                 if (ms_delete_invalid_items_in_folder(handle, scan_data->storage_id, scan_data->msg, is_recursive, scan_data->uid) != MS_MEDIA_ERR_NONE)
941                         MS_DBG_ERR("deleting invalid items in folder failed");
942
943 SCAN_DONE:
944                 MS_DBG_WARN("storage_id = [%s], dir Path = [%.*s], pid = [%d]", scan_data->storage_id, MAX_MSG_SIZE, scan_data->msg, scan_data->pid);
945                 if (ret != MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
946                         if (is_recursive) {
947                                 if (ms_delete_invalid_folder_by_path(handle, scan_data->storage_id, scan_data->msg, scan_data->uid) != MS_MEDIA_ERR_NONE)
948                                         MS_DBG_ERR("deleting invalid folder failed");
949                         }
950
951                         if (noti_type == MS_ITEM_DELETE)
952                                 ms_send_dir_update_noti(scan_data->msg, folder_uuid, noti_type, scan_data->pid);
953
954                         msc_insert_exactor_request(scan_data->msg_type, true, scan_data->storage_id, scan_data->msg, scan_data->pid, scan_data->uid, noti_type);
955                 }
956
957                 if (_msc_is_power_off())
958                         goto _POWEROFF;
959 NEXT:
960                 malloc_trim(0);
961
962                 scan_data->msg_type = MS_MSG_SCANNER_COMPLETE;
963                 msc_send_result(ret, scan_data);
964
965                 g_free(scan_data);
966                 scan_data = NULL;
967                 g_free(folder_uuid);
968                 folder_uuid = NULL;
969
970                 g_directory_scan_processing2 = DIR_SCAN_NON_SCAN;
971                 __msc_del_cur_scan_item();
972                 __msc_del_cancel_scan_item();
973
974                 MS_DBG_WARN("DIRECTORY SCAN END [%d]", ret);
975
976                 ms_disconnect_db(handle);
977                 usleep(SCAN_SLEEP_TIME);
978         }
979
980 _POWEROFF:
981         g_free(scan_data);
982         ms_disconnect_db(handle);
983
984         return NULL;
985 }
986
987 static void __msc_check_pvr_svc(void)
988 {
989         if (!ms_is_support_pvr())
990                 return;
991
992         MS_DBG_ERR("Waiting PVR service");
993         while (!_msc_is_power_off()) {
994                 if (g_file_test("/run/pvr_ready", G_FILE_TEST_EXISTS))
995                         break;
996
997                 sleep(1);
998         }
999
1000         MS_DBG_WARN("PVR service is ready");
1001 }
1002
1003 gpointer msc_storage_scan_thread(gpointer data)
1004 {
1005         int ret = MS_MEDIA_ERR_NONE;
1006         ms_comm_msg_s *scan_data = NULL;
1007         sqlite3 *handle = NULL;
1008         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
1009
1010         while (1) {
1011                 scan_data = g_async_queue_pop(storage_queue2);
1012                 if (scan_data->pid == POWEROFF) {
1013                         MS_DBG_ERR("power off");
1014                         goto _POWEROFF;
1015                 }
1016
1017                 MS_DBG_WARN("STORAGE SCAN START [%.*s][%s]", MAX_MSG_SIZE, scan_data->msg, scan_data->storage_id);
1018
1019                 if (scan_data->msg_type != MS_MSG_STORAGE_ALL &&
1020                         scan_data->msg_type != MS_MSG_STORAGE_PARTIAL &&
1021                         scan_data->msg_type != MS_MSG_STORAGE_INVALID) {
1022                         MS_DBG_ERR("Invalid request[%d]", scan_data->msg_type);
1023                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
1024                         goto NEXT;
1025                 }
1026
1027                 __msc_check_pvr_svc();
1028
1029                 ret = ms_connect_db(&handle, scan_data->uid);
1030                 if (ret != MS_MEDIA_ERR_NONE) {
1031                         MS_DBG_ERR("ms_connect_db failed");
1032                         goto NEXT;
1033                 }
1034
1035                 ret = ms_user_get_storage_type(scan_data->uid, scan_data->msg, &storage_type);
1036                 if (ret != MS_MEDIA_ERR_NONE) {
1037                         MS_DBG_ERR("ms_user_get_storage_type failed");
1038                         goto NEXT;
1039                 }
1040
1041                 ret = __msc_check_memory_status(scan_data->uid);
1042                 if (ret != MS_MEDIA_ERR_NONE) {
1043                         ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_STOP, scan_data->uid);
1044                         MS_DBG_ERR("storage_id = [%s]", scan_data->storage_id);
1045                         msc_insert_exactor_request(scan_data->msg_type, true, scan_data->storage_id, scan_data->msg, scan_data->pid, scan_data->uid, MS_ITEM_UPDATE);
1046                         goto NEXT;
1047                 }
1048
1049                 ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_PROCESSING, scan_data->uid);
1050
1051                 ms_set_db_status(MS_DB_UPDATING, storage_type);
1052
1053                 if (scan_data->msg_type != MS_MSG_STORAGE_INVALID)
1054                         ms_register_start(false, 0);
1055
1056                 if (scan_data->msg_type == MS_MSG_STORAGE_ALL) {
1057                         if (ms_delete_invalid_items(handle, scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
1058                                 MS_DBG_ERR("ms_delete_invalid_items fails");
1059                 }
1060
1061                 ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
1062
1063                 if (scan_data->msg_type != MS_MSG_STORAGE_INVALID)
1064                         ms_register_end(scan_data->uid);
1065
1066                 if (scan_data->msg_type == MS_MSG_STORAGE_PARTIAL && ret == MS_MEDIA_ERR_NONE) {
1067                         ms_delete_invalid_folder(scan_data->storage_id, scan_data->uid);
1068                         ms_delete_invalid_items(handle, scan_data->storage_id, scan_data->uid);
1069                 }
1070
1071                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
1072                         ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_STOP, scan_data->uid);
1073                         ms_set_db_status(MS_DB_STOPPED, storage_type);
1074                 } else {
1075                         ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_COMPLETE, scan_data->uid);
1076                         ms_set_db_status(MS_DB_UPDATED, storage_type);
1077                 }
1078
1079                 MS_DBG_WARN("storage_id = [%s]", scan_data->storage_id);
1080                 msc_insert_exactor_request(scan_data->msg_type, true, scan_data->storage_id, scan_data->msg, scan_data->pid, scan_data->uid, MS_ITEM_UPDATE);
1081
1082 NEXT:
1083                 __msc_del_blocked_path();
1084
1085                 if (_msc_is_power_off())
1086                         goto _POWEROFF;
1087
1088                 ms_disconnect_db(handle);
1089
1090                 malloc_trim(0);
1091
1092                 scan_data->msg_type = MS_MSG_SCANNER_COMPLETE;
1093                 msc_send_result(ret, scan_data);
1094
1095                 g_free(scan_data);
1096                 scan_data = NULL;
1097
1098                 MS_DBG_WARN("STORAGE SCAN END[%d]", ret);
1099
1100                 usleep(SCAN_SLEEP_TIME);
1101         }
1102
1103 _POWEROFF:
1104         g_free(scan_data);
1105         ms_disconnect_db(handle);
1106
1107         return NULL;
1108 }
1109
1110 static int __msc_make_file_list(char *file_path, GPtrArray **path_array, uid_t uid)
1111 {
1112         FILE *fp = NULL;
1113         char buf[MS_FILE_PATH_LEN_MAX] = {0, };
1114         char *path = NULL;
1115         int length;
1116         GPtrArray *_path_array = NULL;
1117         int ret = MS_MEDIA_ERR_NONE;
1118
1119         fp = fopen(file_path, "rt");
1120         MS_DBG_RETVM_IF(!fp, MS_MEDIA_ERR_INTERNAL, "fopen failed");
1121
1122         _path_array = g_ptr_array_new_with_free_func(g_free);
1123
1124         while (fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) {
1125                 /* Remove '\n' */
1126                 length = strlen(buf);
1127                 path = g_strndup(buf, length - 1);
1128
1129                 /* check valid path */
1130                 ret = ms_check_ignore_dir(path, uid);
1131                 if (ret != MS_MEDIA_ERR_NONE) {
1132                         MS_DBG_SERR("Invalid path : %s", path);
1133                         g_free(path);
1134                         continue;
1135                 }
1136
1137                 g_ptr_array_add(_path_array, path);
1138         }
1139
1140         if (fp) fclose(fp);
1141
1142         *path_array = _path_array;
1143
1144         return MS_MEDIA_ERR_NONE;
1145 }
1146
1147 static int __msc_batch_insert(int pid, GPtrArray *path_array, uid_t uid)
1148 {
1149         int ret = MS_MEDIA_ERR_NONE;
1150         sqlite3 *handle = NULL;
1151         char *insert_path = NULL;
1152         char storage_id[MS_UUID_SIZE] = {0,};
1153         int i = 0;
1154
1155         MS_DBG_FENTER();
1156
1157         ret = ms_connect_db(&handle, uid);
1158         MS_DBG_RETV_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_DB_INTERNAL);
1159
1160         ms_register_start(true, pid);
1161
1162         for (i = 0; i < path_array->len; i++) {
1163                 insert_path = g_ptr_array_index(path_array, i);
1164
1165                 memset(storage_id, 0x0, MS_UUID_SIZE);
1166                 if (ms_get_storage_id(handle, insert_path, storage_id, uid) != MS_MEDIA_ERR_NONE) {
1167                         MS_DBG_ERR("There is no storage id in media db");
1168                         continue;
1169                 }
1170
1171                 ret = ms_insert_item_batch(handle, storage_id, insert_path, uid);
1172
1173                 if (_msc_is_power_off()) {
1174                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
1175                         break;
1176                 }
1177         }
1178
1179         /*call for bundle commit*/
1180         ms_register_end(uid);
1181         ms_disconnect_db(handle);
1182
1183         MS_DBG_FLEAVE();
1184
1185         return ret;
1186 }
1187
1188 gpointer msc_register_thread(gpointer data)
1189 {
1190         int ret = MS_MEDIA_ERR_NONE;
1191         ms_comm_msg_s *register_data = NULL;
1192         GPtrArray *path_array = NULL;
1193
1194         while (1) {
1195                 register_data = g_async_queue_pop(reg_queue2);
1196                 if (register_data->pid == POWEROFF) {
1197                         MS_DBG_ERR("power off");
1198                         g_free(register_data);
1199                         return NULL;
1200                 }
1201
1202                 if (register_data->msg_type == MS_MSG_BULK_INSERT) {
1203                         ret = __msc_make_file_list(register_data->msg, &path_array, register_data->uid);
1204                         if (ret == MS_MEDIA_ERR_NONE) {
1205                                 MS_DBG_SLOG("BULK REGISTER START [%.*s]", MAX_MSG_SIZE, register_data->msg);
1206                                 ret = __msc_batch_insert(register_data->pid, path_array, register_data->uid);
1207                                 g_ptr_array_free(path_array, TRUE);
1208                                 path_array = NULL;
1209                                 MS_DBG_WARN("BULK REGISTER END [%d]", ret);
1210                         } else {
1211                                 MS_DBG_ERR("__msc_make_file_list failed [%d]", ret);
1212                         }
1213                 } else {
1214
1215                         MS_DBG_ERR("invalid message type [%d]", register_data->msg_type);
1216                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
1217                 }
1218
1219                 /*Active flush */
1220                 malloc_trim(0);
1221
1222                 msc_send_result(ret, register_data);
1223                 g_free(register_data);
1224         }                       /*thread while*/
1225
1226         return NULL;
1227 }
1228
1229 int msc_set_cancel_scan_item(const char* cancel_path, int pid)
1230 {
1231         int ret = -1;
1232         MS_DBG_WARN("msc_set_cancel_scan_item begin");
1233         g_mutex_lock(&scan_item_mutex);
1234         if (cancel_path == NULL) {
1235                 MS_DBG_ERR("cancel_path invalid...");
1236                 return ret;
1237         }
1238
1239         if (cur_scan_item != NULL && cur_scan_item->path != NULL) {
1240                 MS_DBG_SWARN("cur_scan_item->path[%s], cur_scan_item->pid[%d]", cur_scan_item->path, cur_scan_item->pid);
1241                 MS_DBG_SWARN("cancel_path[%s], pid[%d]", cancel_path, pid);
1242                 if ((strcmp(cur_scan_item->path, cancel_path) == 0) && (pid == cur_scan_item->pid))
1243                         ret = __msc_set_scan_item(&cancel_scan_item, cancel_path, pid);
1244                 else if ((pid == -1) && (strncmp(cur_scan_item->path, cancel_path, strlen(cancel_path)) == 0))
1245                         ret = __msc_set_scan_item(&cancel_scan_item, cancel_path, pid);
1246         } else {
1247                 MS_DBG_ERR("cur_scan_item == NULL || cur_scan_item->path == NULL");
1248         }
1249         g_mutex_unlock(&scan_item_mutex);
1250
1251         MS_DBG_WARN("msc_set_cancel_scan_item end");
1252         return ret;
1253 }
1254
1255 void msc_set_blocked_path(const char *blocked_path)
1256 {
1257         MS_DBG_FENTER();
1258
1259         g_mutex_lock(&blocked_mutex2);
1260
1261         if (g_blocked_path2 != NULL) {
1262                 MS_DBG_SWARN("g_blocked_path is not NULL [%s]", g_blocked_path2);
1263                 g_free(g_blocked_path2);
1264         }
1265
1266         g_blocked_path2 = g_strdup(blocked_path);
1267
1268         g_mutex_unlock(&blocked_mutex2);
1269
1270         MS_DBG_FLEAVE();
1271 }
1272
1273 static void __msc_del_blocked_path(void)
1274 {
1275         MS_DBG_FENTER();
1276
1277         g_mutex_lock(&blocked_mutex2);
1278
1279         if (g_blocked_path2 != NULL) {
1280                 MS_DBG_SWARN("g_blocked_path is not NULL [%s]", g_blocked_path2);
1281                 MS_SAFE_FREE(g_blocked_path2);
1282         }
1283
1284         g_mutex_unlock(&blocked_mutex2);
1285
1286         MS_DBG_FLEAVE();
1287 }
1288
1289 static int __msc_check_memory_status(uid_t uid)
1290 {
1291         int ret = MS_MEDIA_ERR_NONE;
1292         double db_size = 0.0;
1293
1294         /*check remain space*/
1295         ret = __msc_check_remain_space(uid);
1296         MS_DBG_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
1297
1298         /*check db size*/
1299         ms_check_size_mediadb(uid, &db_size);
1300         if (db_size >= MEDIA_DB_SIZE_LIMIT_1) {
1301                 MS_DBG_ERR("DB SIZE [%lf] REACH THE FIRST LIMIT [%lf]", db_size, MEDIA_DB_SIZE_LIMIT_1);
1302                 return MS_MEDIA_ERR_DB_LIMIT_1;
1303         }
1304
1305         return MS_MEDIA_ERR_NONE;
1306 }
1307
1308 static int __msc_check_remain_space(uid_t uid)
1309 {
1310         int err = MS_MEDIA_ERR_NONE;
1311         double free_space = 0.0;
1312         double db_size = 0.0;
1313
1314         err = ms_get_remain_space(&free_space);
1315         if (err != MS_MEDIA_ERR_NONE) {
1316                 MS_DBG_ERR("ms_get_remain_space failed");
1317         } else {
1318                 if (free_space < MEDIA_DB_SPACE_LIMIT) {
1319                         MS_DBG_ERR("NOT ENOUGH SPACE WE DO NOT UPDATE MEDIA DB FREE SPACE [%lf]", free_space);
1320
1321                         ms_config_set_int(MS_DB_LIMIT, 0);
1322
1323                         return MS_MEDIA_ERR_NOT_ENOUGH_SPACE;
1324                 }
1325         }
1326
1327         err = ms_check_size_mediadb(uid, &db_size);
1328         if (err != MS_MEDIA_ERR_NONE) {
1329                 MS_DBG_ERR("msc_check_dbsize failed");
1330         } else {
1331                 if (db_size >= MEDIA_DB_SIZE_LIMIT_2) {
1332                         MS_DBG_ERR("REACH LIMIT DB SIZE [%lf]", db_size);
1333
1334                         MS_DBG_ERR("START REMOVE INVALID DATA");
1335                         msc_cleanup_invalid_values(uid);
1336                         MS_DBG_ERR("END REMOVE INVALID DATA");
1337
1338                         ms_check_size_mediadb(uid, &db_size);
1339                         if (db_size >= MEDIA_DB_SIZE_LIMIT_2) {
1340
1341                                 ms_config_set_int(MS_DB_LIMIT, 0);
1342
1343                                 MS_DBG_ERR("DB IS FULL. CANNOT UPDATE[%lf]", db_size);
1344                                 return MS_MEDIA_ERR_DB_FULL_FAIL;
1345                         }
1346                 }
1347         }
1348
1349         return MS_MEDIA_ERR_NONE;
1350 }
1351
1352 void msc_init_scanner(void)
1353 {
1354         if (!scan_queue2) scan_queue2 = g_async_queue_new();
1355         if (!reg_queue2) reg_queue2 = g_async_queue_new();
1356         if (!storage_queue2) storage_queue2 = g_async_queue_new();
1357 }
1358
1359 void msc_deinit_scanner(void)
1360 {
1361         if (scan_queue2) g_async_queue_unref(scan_queue2);
1362         if (reg_queue2) g_async_queue_unref(reg_queue2);
1363         if (storage_queue2) g_async_queue_unref(storage_queue2);
1364 }
1365
1366 int msc_push_scan_request(ms_scan_type_e scan_type, ms_comm_msg_s *recv_msg)
1367 {
1368         int ret = MS_MEDIA_ERR_NONE;
1369
1370         switch (scan_type) {
1371         case MS_SCAN_STORAGE:
1372                 g_async_queue_push(storage_queue2, recv_msg);
1373                 break;
1374         case MS_SCAN_DIRECTORY:
1375                 g_async_queue_push(scan_queue2, recv_msg);
1376                 break;
1377         case MS_SCAN_REGISTER:
1378                 g_async_queue_push(reg_queue2, recv_msg);
1379                 break;
1380         default:
1381                 MS_DBG_ERR("invalid parameter");
1382                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
1383                 break;
1384         }
1385
1386         return ret;
1387 }
1388
1389 void msc_send_power_off_request(void)
1390 {
1391         ms_comm_msg_s *data = NULL;
1392
1393         if (scan_queue2) {
1394                 data = g_new0(ms_comm_msg_s, 1);
1395
1396                 data->pid = POWEROFF;
1397                 msc_push_scan_request(MS_SCAN_DIRECTORY, data);
1398         }
1399
1400         if (reg_queue2) {
1401                 data = g_new0(ms_comm_msg_s, 1);
1402
1403                 data->pid = POWEROFF;
1404                 msc_push_scan_request(MS_SCAN_REGISTER, data);
1405         }
1406
1407         if (storage_queue2) {
1408                 data = g_new0(ms_comm_msg_s, 1);
1409
1410                 data->pid = POWEROFF;
1411                 msc_push_scan_request(MS_SCAN_STORAGE, data);
1412         }
1413 }
1414
1415 void msc_remove_dir_scan_request(ms_comm_msg_s *recv_msg)
1416 {
1417         char *cancel_path = recv_msg->msg;
1418         int pid = recv_msg->pid;
1419         int i = 0;
1420         int len = g_async_queue_length(scan_queue2);
1421         ms_comm_msg_s *msg = NULL;
1422         GAsyncQueue *temp_scan_queue = NULL;
1423
1424         MS_DBG_WARN("scan_req_mutex2 is LOCKED");
1425         g_mutex_lock(&scan_req_mutex2);
1426
1427         if (len <= 0 && g_directory_scan_processing2 == 0) {
1428                 MS_DBG_WARN("Request is not stacked[%d]", len);
1429                 goto END_REMOVE_REQUEST;
1430         }
1431
1432         MS_DBG_WARN("len == [%d] pid=[%d], cancel_path[%s]", len, pid, cancel_path);
1433
1434         msc_set_cancel_scan_item(recv_msg->msg, recv_msg->pid);
1435
1436         if (len > 0) {
1437                 temp_scan_queue = g_async_queue_new();
1438
1439                 MS_DBG_WARN("start update scan_queue2");
1440                 for (i = 0; i < len; i++) {
1441                         /*create new queue to compare request*/
1442                         msg = g_async_queue_pop(scan_queue2);
1443                         MS_DBG_WARN("msg->msg[%.*s], msg->pid[%d]", MAX_MSG_SIZE, msg->msg, msg->pid);
1444                         if ((strcmp(msg->msg, cancel_path) == 0) && (pid == msg->pid)) {
1445                                 msg->msg_type = MS_MSG_DIRECTORY_SCANNING_CANCEL;
1446                                 msc_send_result(MS_MEDIA_ERR_SCANNER_FORCE_STOP, msg);
1447                                 g_free(msg);
1448                         } else {
1449                                 g_async_queue_push(temp_scan_queue, msg);
1450                         }
1451                 }
1452
1453                 len = g_async_queue_length(temp_scan_queue);
1454                 int j = 0;
1455                 for (; j < len; j++) {
1456                         msg = g_async_queue_pop(temp_scan_queue);
1457                         g_async_queue_push(scan_queue2, msg);
1458                 }
1459                 g_async_queue_unref(temp_scan_queue);
1460                 MS_DBG_WARN("end update scan_queue2");
1461         }
1462
1463 END_REMOVE_REQUEST:
1464         msc_set_cancel_extract_item(recv_msg->msg, recv_msg->pid);
1465         msc_remove_folder_extract_request(recv_msg);
1466
1467         g_mutex_unlock(&scan_req_mutex2);
1468         MS_DBG_WARN("scan_req_mutex2 is UNLOCKED");
1469 }
1470