Fix to stop scanning when power off
[platform/core/multimedia/media-server.git] / src / scanner / media-scanner-scan.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.h"
30 #include "media-scanner-socket.h"
31 #include "media-scanner-scan.h"
32
33 static bool power_off;
34 static GAsyncQueue * storage_queue;
35 static GAsyncQueue *scan_queue;
36 static GAsyncQueue *reg_queue;
37 static GMutex scan_req_mutex;
38
39 static bool __msc_is_power_off(void)
40 {
41         if (power_off) {
42                 MS_DBG_ERR("Power off");
43                 return true;
44         }
45
46         return false;
47 }
48
49 static int __msc_dir_scan(sqlite3 *handle, const char *storage_id, char *start_path, bool check_exists, bool is_recursive, uid_t uid)
50 {
51         int ret = MS_MEDIA_ERR_NONE;
52         GDir *dir = NULL;
53         GError *error = NULL;
54         const char *name;
55         GPtrArray *dir_array = NULL;
56         char *current_path = NULL;
57         char *path = NULL;
58         int (*scan_function)(sqlite3 *, const char*, const char*, uid_t) = NULL;
59
60         dir_array = g_ptr_array_new();
61         g_ptr_array_add(dir_array, start_path);
62
63         scan_function = (check_exists == false) ? ms_insert_item_batch : ms_validate_item;
64
65         while (dir_array->len != 0) {
66                 current_path = g_ptr_array_index(dir_array, 0);
67                 g_ptr_array_remove_index(dir_array, 0);
68
69                 if (__msc_is_power_off()) {
70                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
71                         MS_SAFE_FREE(current_path);
72                         break;
73                 }
74
75                 if (ms_check_scan_ignore(current_path, uid) != MS_MEDIA_ERR_NONE) {
76                         MS_DBG_SERR("%s is ignore", current_path);
77                         MS_SAFE_FREE(current_path);
78                         continue;
79                 }
80
81                 dir = g_dir_open(current_path, 0, &error);
82                 if (error != NULL) {
83                         MS_DBG_ERR("g_dir_open fails [%s]", current_path);
84                         MS_SAFE_FREE(current_path);
85                         g_error_free(error);
86                         error = NULL;
87                         continue;
88                 }
89
90                 if (ms_insert_folder(handle, storage_id, current_path, uid) != MS_MEDIA_ERR_NONE)
91                         MS_DBG_ERR("insert folder failed");
92
93                 while ((name = g_dir_read_name(dir))) {
94                         if (__msc_is_power_off()) {
95                                 ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
96                                 break;
97                         }
98
99                         if (name[0] == '.')
100                                 continue;
101
102                         path = g_build_path(G_DIR_SEPARATOR_S, current_path, name, NULL);
103
104                         if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
105                                 /* Check symbolic link file */
106                                 if (g_file_test(path, G_FILE_TEST_IS_SYMLINK)) {
107                                         MS_DBG_WARN("Symbolic link.. Skip this file");
108                                         MS_SAFE_FREE(path);
109                                         continue;
110                                 }
111
112                                 /* Check content.scanning.others feature */
113                                 if (!ms_check_support_media_type(path)) {
114                                         MS_DBG("Unsupported media type");
115                                         MS_SAFE_FREE(path);
116                                         continue;
117                                 }
118
119                                 if (scan_function(handle, storage_id, path, uid) != MS_MEDIA_ERR_NONE)
120                                         MS_DBG_ERR("failed to update db");
121
122                                 MS_SAFE_FREE(path);
123                         } else {
124                                 if (is_recursive) {
125                                         g_ptr_array_add(dir_array, path);
126                                 } else {
127                                         ret = ms_insert_folder(handle, storage_id, path, uid);
128                                         if (ret != MS_MEDIA_ERR_NONE)
129                                                 MS_DBG_ERR("ms_insert_folder failed");
130                                         MS_SAFE_FREE(path);
131                                 }
132                         }
133                 }
134
135                 MS_SAFE_FREE(current_path);
136
137                 if (dir)
138                         g_dir_close(dir);
139         }
140
141         g_ptr_array_free(dir_array, TRUE);
142
143         return ret;
144 }
145
146 static int __msc_db_update(sqlite3 *handle, const char *storage_id, const ms_comm_msg_s * scan_data)
147 {
148         int scan_type;
149         int err = MS_MEDIA_ERR_NONE;
150         char *start_path = NULL;
151
152         scan_type = scan_data->msg_type;
153         start_path = g_strdup(scan_data->msg);
154
155         if (scan_type != MS_MSG_STORAGE_INVALID) {
156                 MS_DBG_INFO("INSERT");
157                 if (scan_type == MS_MSG_STORAGE_ALL)
158                         err = __msc_dir_scan(handle, storage_id, start_path, false, true, scan_data->uid);
159                 else
160                         err = __msc_dir_scan(handle, storage_id, start_path, true, true, scan_data->uid);
161
162                 if (err != MS_MEDIA_ERR_NONE)
163                         MS_DBG_ERR("error : %d", err);
164
165         } else {
166                 MS_DBG_INFO("INVALID");
167                 err = ms_validity_change_all_items(handle, storage_id, false, scan_data->uid);
168                 if (err != MS_MEDIA_ERR_NONE)
169                         MS_DBG_ERR("error : %d", err);
170
171                 ms_set_folder_validity(handle, storage_id, start_path, 0, true, scan_data->uid);
172
173                 g_free(start_path);
174         }
175
176         sync();
177
178         return err;
179 }
180
181 static int __msc_directory_scan_insert_only(sqlite3 *handle, ms_comm_msg_s *scan_data, bool is_recursive)
182 {
183         int ret = MS_MEDIA_ERR_NONE;
184         char *start_path = NULL;
185         char *folder_uuid = NULL;
186
187         MS_DBG_RETVM_IF(!handle, MS_MEDIA_ERR_INVALID_PARAMETER, "handle is NULL");
188         MS_DBG_RETVM_IF(!scan_data, MS_MEDIA_ERR_INVALID_PARAMETER, "scan_data is NULL");
189
190         start_path = g_strdup(scan_data->msg);
191
192         ms_batch_commit_enable(false, 0);
193         ret = __msc_dir_scan(handle, scan_data->storage_id, start_path, false, is_recursive, scan_data->uid);
194         ms_batch_commit_disable(scan_data->uid);
195
196         if (ret != MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
197                 MS_DBG_INFO("working normally");
198                 ret = ms_get_folder_id(handle, scan_data->storage_id, scan_data->msg, &folder_uuid);
199                 MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_get_folder_id failed");
200                 ret = ms_send_dir_update_noti(scan_data->msg, folder_uuid, MS_ITEM_INSERT, scan_data->pid);
201
202                 MS_SAFE_FREE(folder_uuid);
203         }
204
205         return ret;
206 }
207
208 static int __msc_directory_scan_update_and_delete(sqlite3 *handle, ms_comm_msg_s *scan_data, bool is_recursive, int noti_type)
209 {
210         int ret = MS_MEDIA_ERR_NONE;
211         char *start_path = NULL;
212         char *folder_uuid = NULL;
213
214         MS_DBG_RETVM_IF(!handle, MS_MEDIA_ERR_INVALID_PARAMETER, "handle is NULL");
215         MS_DBG_RETVM_IF(!scan_data, MS_MEDIA_ERR_INVALID_PARAMETER, "scan_data is NULL");
216
217         ret = ms_set_folder_validity(handle, scan_data->storage_id, scan_data->msg, MS_SCANNING, is_recursive, scan_data->uid);
218         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "set_folder_validity failed");
219
220         ret = ms_set_folder_item_validity(handle, scan_data->storage_id, scan_data->msg, MS_SCANNING, is_recursive, scan_data->uid);
221         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_set_folder_item_validity failed");
222
223         start_path = g_strdup(scan_data->msg);
224
225         ret = ms_get_folder_id(handle, scan_data->storage_id, scan_data->msg, &folder_uuid);
226         if (ret != MS_MEDIA_ERR_NONE) {
227                 MS_DBG_ERR("ms_get_folder_id failed");
228                 g_free(start_path);
229                 return ret;
230         }
231
232         ms_batch_commit_enable(false, 0);
233         ret = __msc_dir_scan(handle, scan_data->storage_id, start_path, true, is_recursive, scan_data->uid);
234         ms_batch_commit_disable(scan_data->uid);
235
236         if (ms_delete_invalid_items(handle, scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
237                 MS_DBG_ERR("deleting invalid items in storage failed");
238
239         if (ms_delete_invalid_folder(scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
240                 MS_DBG_ERR("deleting invalid folders in storage failed");
241
242         if (ret != MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
243                 MS_DBG_INFO("working normally");
244                 ret = ms_send_dir_update_noti(scan_data->msg, folder_uuid, noti_type, scan_data->pid);
245         }
246
247         g_free(folder_uuid);
248
249         return ret;
250 }
251
252 gpointer msc_directory_scan_thread(gpointer data)
253 {
254         int ret = MS_MEDIA_ERR_NONE;
255         sqlite3 *handle = NULL;
256         ms_comm_msg_s *scan_data = NULL;
257         bool is_recursive = true;
258
259         while (1) {
260                 scan_data = g_async_queue_pop(scan_queue);
261                 if (scan_data->pid == POWEROFF) {
262                         MS_DBG_ERR("power off");
263                         goto _POWEROFF;
264                 }
265
266                 MS_DBG_WARN("DIRECTORY SCAN START [%.*s][%s][%d]", MAX_MSG_SIZE, scan_data->msg, scan_data->storage_id, scan_data->msg_type);
267
268                 if (strlen(scan_data->storage_id) == 0) {
269                         MS_DBG_ERR("storage_id length is 0");
270                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
271                         goto NEXT;
272                 }
273
274                 if (scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING && scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
275                         MS_DBG_ERR("Invalid request");
276                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
277                         goto NEXT;
278                 }
279
280                 ret = ms_connect_db(&handle, scan_data->uid);
281                 if (ret != MS_MEDIA_ERR_NONE) {
282                         MS_DBG_ERR("ms_connect_db failed");
283                         goto NEXT;
284                 }
285
286                 ms_trim_dir_path(scan_data->msg);
287                 is_recursive = (scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) ? false : true;
288
289                 if (g_file_test(scan_data->msg, G_FILE_TEST_IS_DIR)) {
290                         if (ms_check_folder_exist(handle, scan_data->storage_id, scan_data->msg) == MS_MEDIA_ERR_NONE) {
291                                 MS_DBG_WARN("[%.*s] already exist", MAX_MSG_SIZE, scan_data->msg);
292                                 ret = __msc_directory_scan_update_and_delete(handle, scan_data, is_recursive, MS_ITEM_UPDATE);
293                         } else {
294                                 MS_DBG_WARN("[%.*s] new insert path", MAX_MSG_SIZE, scan_data->msg);
295                                 ret = __msc_directory_scan_insert_only(handle, scan_data, is_recursive);
296                         }
297                 } else {
298                         MS_DBG_WARN("[%.*s] delete path", MAX_MSG_SIZE, scan_data->msg);
299                         ret = __msc_directory_scan_update_and_delete(handle, scan_data, true, MS_ITEM_DELETE);
300                 }
301
302                 ms_disconnect_db(handle);
303
304                 if (__msc_is_power_off())
305                         goto _POWEROFF;
306 NEXT:
307                 /*Active flush */
308                 malloc_trim(0);
309
310                 msc_send_result(ret, scan_data);
311                 g_free(scan_data);
312                 MS_DBG_INFO("DIRECTORY SCAN END [%d]", ret);
313         }                       /*thread while*/
314
315 _POWEROFF:
316         g_free(scan_data);
317
318         return NULL;
319 }
320
321 static int __msc_storage_scan_partial(ms_comm_msg_s *scan_data, ms_user_storage_type_e storage_type)
322 {
323         int ret = MS_MEDIA_ERR_NONE;
324         sqlite3 *handle = NULL;
325
326         ret = ms_connect_db(&handle, scan_data->uid);
327         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_connect_db failed");
328
329         ms_set_db_status(MS_DB_UPDATING, storage_type);
330
331         ret = ms_validity_change_all_items(handle, scan_data->storage_id, false, scan_data->uid);
332         if (ret != MS_MEDIA_ERR_NONE) {
333                 MS_DBG_ERR("ms_validity_change_all_items failed");
334                 ms_disconnect_db(handle);
335
336                 return ret;
337         }
338
339         ms_batch_commit_enable(false, 0);
340         ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
341         ms_batch_commit_disable(scan_data->uid);
342
343         if (ms_delete_invalid_items(handle, scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
344                 MS_DBG_ERR("deleting invalid items in storage failed");
345
346         if (ms_delete_invalid_folder(scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
347                 MS_DBG_ERR("deleting invalid folders in storage failed");
348
349         ms_disconnect_db(handle);
350
351         return ret;
352 }
353
354 static int __msc_storage_scan_all(ms_comm_msg_s *scan_data, ms_user_storage_type_e storage_type)
355 {
356         int ret = MS_MEDIA_ERR_NONE;
357         sqlite3 *handle = NULL;
358
359         ret = ms_connect_db(&handle, scan_data->uid);
360         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_connect_db failed");
361
362         ms_set_db_status(MS_DB_UPDATING, storage_type);
363
364         ms_batch_commit_enable(false, 0);
365         ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
366         ms_batch_commit_disable(scan_data->uid);
367
368         ms_disconnect_db(handle);
369
370         return ret;
371 }
372
373 gpointer msc_storage_scan_thread(gpointer data)
374 {
375         int ret = MS_MEDIA_ERR_NONE;
376         ms_comm_msg_s *scan_data = NULL;
377         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
378
379         while (1) {
380                 scan_data = g_async_queue_pop(storage_queue);
381                 if (scan_data->pid == POWEROFF) {
382                         MS_DBG_WARN("power off");
383                         goto _POWEROFF;
384                 }
385
386                 MS_DBG_WARN("STORAGE SCAN START [%.*s][%s]", MAX_MSG_SIZE, scan_data->msg, scan_data->storage_id);
387
388                 if (strlen(scan_data->storage_id) == 0) {
389                         MS_DBG_ERR("storage_id length is 0");
390                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
391                         goto NEXT;
392                 }
393
394                 ret = ms_user_get_storage_type(scan_data->uid, scan_data->msg, &storage_type);
395                 if (ret != MS_MEDIA_ERR_NONE) {
396                         MS_DBG_ERR("ms_user_get_storage_type failed");
397                         goto NEXT;
398                 }
399
400                 if (scan_data->msg_type == MS_MSG_STORAGE_PARTIAL) {
401                         ret = __msc_storage_scan_partial(scan_data, storage_type);
402                 } else if (scan_data->msg_type == MS_MSG_STORAGE_ALL || scan_data->msg_type == MS_MSG_STORAGE_INVALID) {
403                         ret = __msc_storage_scan_all(scan_data, storage_type);
404                 } else {
405                         MS_DBG_ERR("Invalid request[%d]", scan_data->msg_type);
406                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
407                         goto NEXT;
408                 }
409
410                 /* send notification */
411                 ms_send_dir_update_noti(scan_data->msg, NULL, MS_ITEM_UPDATE, scan_data->pid);
412
413                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP)
414                         ms_set_db_status(MS_DB_STOPPED, storage_type);
415                 else
416                         ms_set_db_status(MS_DB_UPDATED, storage_type);
417 NEXT:
418                 if (__msc_is_power_off())
419                         goto _POWEROFF;
420
421                 /*Active flush */
422                 malloc_trim(0);
423
424                 msc_send_result(ret, scan_data);
425                 g_free(scan_data);
426
427                 MS_DBG_WARN("STORAGE SCAN END[%d]", ret);
428         }                       /*thread while*/
429 _POWEROFF:
430         g_free(scan_data);
431
432         return NULL;
433 }
434
435 static int __msc_make_file_list(char *file_path, GPtrArray **path_array, uid_t uid)
436 {
437         FILE *fp = NULL;
438         char buf[MS_FILE_PATH_LEN_MAX] = {0, };
439         char *path = NULL;
440         int length;
441         GPtrArray *_path_array = NULL;
442         int ret = MS_MEDIA_ERR_NONE;
443
444         fp = fopen(file_path, "rt");
445         MS_DBG_RETVM_IF(!fp, MS_MEDIA_ERR_INTERNAL, "fopen failed");
446
447         _path_array = g_ptr_array_new_with_free_func(g_free);
448
449         while (fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) {
450                 /* Remove '\n' */
451                 length = strlen(buf);
452                 path = g_strndup(buf, length - 1);
453
454                 /* check valid path */
455                 ret = ms_check_ignore_dir(path, uid);
456                 if (ret != MS_MEDIA_ERR_NONE) {
457                         MS_DBG_SERR("invalide path : %s", path);
458                         g_free(path);
459                         continue;
460                 }
461
462                 g_ptr_array_add(_path_array, path);
463         }
464
465         if (fp) fclose(fp);
466
467         *path_array = _path_array;
468
469         return MS_MEDIA_ERR_NONE;
470 }
471
472 static int __msc_batch_insert(int pid, GPtrArray *path_array, uid_t uid)
473 {
474         int ret = MS_MEDIA_ERR_NONE;
475         sqlite3 *handle = NULL;
476         char *insert_path = NULL;
477         char storage_id[MS_UUID_SIZE] = {0,};
478         int i = 0;
479
480         MS_DBG_FENTER();
481
482         ret = ms_connect_db(&handle, uid);
483         MS_DBG_RETV_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_DB_INTERNAL);
484
485         ms_batch_commit_enable(true, pid);
486
487         for (i = 0; i < path_array->len; i++) {
488                 insert_path = g_ptr_array_index(path_array, i);
489
490                 memset(storage_id, 0x0, MS_UUID_SIZE);
491                 if (ms_get_storage_id(handle, insert_path, storage_id, uid) != MS_MEDIA_ERR_NONE) {
492                         MS_DBG_ERR("There is no storage id in media db");
493                         continue;
494                 }
495
496                 ret = ms_insert_item_batch(handle, storage_id, insert_path, uid);
497
498                 if (__msc_is_power_off()) {
499                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
500                         break;
501                 }
502         }
503
504         /*call for bundle commit*/
505         ms_batch_commit_disable(uid);
506         ms_disconnect_db(handle);
507
508         MS_DBG_FLEAVE();
509
510         return ret;
511 }
512
513 gpointer msc_register_thread(gpointer data)
514 {
515         int ret = MS_MEDIA_ERR_NONE;
516         ms_comm_msg_s *register_data = NULL;
517         GPtrArray *path_array = NULL;
518
519         while (1) {
520                 register_data = g_async_queue_pop(reg_queue);
521
522                 if (register_data->pid == POWEROFF) {
523                         MS_DBG_ERR("power off");
524                         g_free(register_data);
525                         return NULL;
526                 }
527
528                 if (register_data->msg_type == MS_MSG_BULK_INSERT) {
529                         ret = __msc_make_file_list(register_data->msg, &path_array, register_data->uid);
530                         if (ret == MS_MEDIA_ERR_NONE) {
531                                 MS_DBG_SLOG("BULK REGISTER START [%.*s]", MAX_MSG_SIZE, register_data->msg);
532                                 ret = __msc_batch_insert(register_data->pid, path_array, register_data->uid);
533                                 g_ptr_array_free(path_array, TRUE);
534                                 path_array = NULL;
535                                 MS_DBG_WARN("BULK REGISTER END [%d]", ret);
536                         } else {
537                                 MS_DBG_ERR("__msc_make_file_list failed [%d]", ret);
538                         }
539                 } else {
540
541                         MS_DBG_ERR("invalid message type [%d]", register_data->msg_type);
542                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
543                 }
544
545                 /*Active flush */
546                 malloc_trim(0);
547
548                 msc_send_result(ret, register_data);
549                 g_free(register_data);
550         }                       /*thread while*/
551
552         return NULL;
553 }
554
555 static gpointer __msc_metadata_update_thread(gpointer data)
556 {
557         ms_comm_msg_s *scan_data = data;
558         int ret = MS_MEDIA_ERR_NONE;
559         sqlite3 *handle = NULL;
560
561         ret = ms_connect_db(&handle, scan_data->uid);
562         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, NULL, "ms_connect_db failed");
563
564         MS_DBG_INFO("META UPDATE START");
565
566         ret = ms_update_meta_batch(handle, scan_data->uid);
567         ms_disconnect_db(handle);
568
569         msc_send_result(ret, scan_data);
570         g_free(scan_data);
571
572         MS_DBG_INFO("META UPDATE END [%d]", ret);
573
574         return NULL;
575 }
576
577 void msc_metadata_update_thread(ms_comm_msg_s *recv_msg)
578 {
579         GThread *update_thread = g_thread_new("metadata_update_thread", __msc_metadata_update_thread, recv_msg);
580         g_thread_join(update_thread);
581 }
582
583 void msc_init_scanner(void)
584 {
585         if (!scan_queue) scan_queue = g_async_queue_new();
586         if (!reg_queue) reg_queue = g_async_queue_new();
587         if (!storage_queue) storage_queue = g_async_queue_new();
588
589         /*Init mutex variable*/
590         g_mutex_init(&scan_req_mutex);
591
592 }
593
594 void msc_deinit_scanner(void)
595 {
596         if (scan_queue) g_async_queue_unref(scan_queue);
597         if (reg_queue) g_async_queue_unref(reg_queue);
598         if (storage_queue) g_async_queue_unref(storage_queue);
599
600         /*Clear db mutex variable*/
601         g_mutex_clear(&scan_req_mutex);
602
603 }
604
605 int msc_push_scan_request(ms_scan_type_e scan_type, ms_comm_msg_s *recv_msg)
606 {
607         int ret = MS_MEDIA_ERR_NONE;
608
609         switch (scan_type) {
610         case MS_SCAN_STORAGE:
611                 g_async_queue_push(storage_queue, recv_msg);
612                 break;
613         case MS_SCAN_DIRECTORY:
614                 g_async_queue_push(scan_queue, recv_msg);
615                 break;
616         case MS_SCAN_REGISTER:
617                 g_async_queue_push(reg_queue, recv_msg);
618                 break;
619         default:
620                 MS_DBG_ERR("invalid parameter");
621                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
622                 break;
623         }
624
625         return ret;
626 }
627
628 void msc_send_power_off_request(void)
629 {
630         ms_comm_msg_s *data = NULL;
631
632         power_off = true;
633
634         if (scan_queue) {
635                 /*notify to scannig thread*/
636                 data = g_new0(ms_comm_msg_s, 1);
637
638                 data->pid = POWEROFF;
639                 msc_push_scan_request(MS_SCAN_DIRECTORY, data);
640         }
641
642         if (reg_queue) {
643                 /*notify to register thread*/
644                 data = g_new0(ms_comm_msg_s, 1);
645
646                 data->pid = POWEROFF;
647                 msc_push_scan_request(MS_SCAN_REGISTER, data);
648         }
649
650         if (storage_queue) {
651                 /*notify to register thread*/
652                 data = g_new0(ms_comm_msg_s, 1);
653
654                 data->pid = POWEROFF;
655                 msc_push_scan_request(MS_SCAN_STORAGE, data);
656         }
657 }
658
659 void msc_remove_dir_scan_request(ms_comm_msg_s *recv_msg)
660 {
661         int i = 0;
662         ms_comm_msg_s *msg = NULL;
663         GAsyncQueue *temp_scan_queue = NULL;
664         int queue_len = g_async_queue_length(scan_queue);
665
666         if (queue_len == 0) {
667                 MS_DBG_ERR("Request is not stacked");
668                 return;
669         }
670
671         MS_DBG_WARN("scan_req_mutex is LOCKED");
672         g_mutex_lock(&scan_req_mutex);
673
674         temp_scan_queue = g_async_queue_new();
675
676         for (i = 0; i < queue_len; i++) {
677                 /*create new queue to compare request*/
678                 msg = g_async_queue_pop(scan_queue);
679                 if ((g_strcmp0(msg->msg, recv_msg->msg) == 0) && (recv_msg->pid == msg->pid)) {
680                         MS_DBG("Find request. Remove it");
681                         g_free(msg);
682                 } else {
683                         g_async_queue_push(temp_scan_queue, msg);
684                 }
685         }
686         g_async_queue_unref(scan_queue);
687         scan_queue = temp_scan_queue;
688
689         g_mutex_unlock(&scan_req_mutex);
690         MS_DBG_WARN("scan_req_mutex is UNLOCKED");
691 }