9e8dcf733cd898b3c8e0d6732d43cebb865f0f9b
[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 &&
275                         scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
276                         MS_DBG_ERR("Invalid request");
277                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
278                         goto NEXT;
279                 }
280
281                 ret = ms_connect_db(&handle, scan_data->uid);
282                 if (ret != MS_MEDIA_ERR_NONE) {
283                         MS_DBG_ERR("ms_connect_db failed");
284                         goto NEXT;
285                 }
286
287                 ms_trim_dir_path(scan_data->msg);
288                 is_recursive = (scan_data->msg_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) ? false : true;
289
290                 if (g_file_test(scan_data->msg, G_FILE_TEST_IS_DIR)) {
291                         if (ms_check_folder_exist(handle, scan_data->storage_id, scan_data->msg) == MS_MEDIA_ERR_NONE) {
292                                 MS_DBG_WARN("[%.*s] already exist", MAX_MSG_SIZE, scan_data->msg);
293                                 ret = __msc_directory_scan_update_and_delete(handle, scan_data, is_recursive, MS_ITEM_UPDATE);
294                         } else {
295                                 MS_DBG_WARN("[%.*s] new insert path", MAX_MSG_SIZE, scan_data->msg);
296                                 ret = __msc_directory_scan_insert_only(handle, scan_data, is_recursive);
297                         }
298                 } else {
299                         MS_DBG_WARN("[%.*s] delete path", MAX_MSG_SIZE, scan_data->msg);
300                         ret = __msc_directory_scan_update_and_delete(handle, scan_data, true, MS_ITEM_DELETE);
301                 }
302
303                 ms_disconnect_db(handle);
304
305                 if (__msc_is_power_off())
306                         goto _POWEROFF;
307 NEXT:
308                 /*Active flush */
309                 malloc_trim(0);
310
311                 msc_send_result(ret, scan_data);
312                 g_free(scan_data);
313                 MS_DBG_INFO("DIRECTORY SCAN END [%d]", ret);
314         }                       /*thread while*/
315
316 _POWEROFF:
317         g_free(scan_data);
318
319         return NULL;
320 }
321
322 static int __msc_storage_scan_partial(ms_comm_msg_s *scan_data, ms_user_storage_type_e storage_type)
323 {
324         int ret = MS_MEDIA_ERR_NONE;
325         sqlite3 *handle = NULL;
326
327         ret = ms_connect_db(&handle, scan_data->uid);
328         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_connect_db failed");
329
330         ms_set_db_status(MS_DB_UPDATING, storage_type);
331
332         ret = ms_validity_change_all_items(handle, scan_data->storage_id, false, scan_data->uid);
333         if (ret != MS_MEDIA_ERR_NONE) {
334                 MS_DBG_ERR("ms_validity_change_all_items failed");
335                 ms_disconnect_db(handle);
336
337                 return ret;
338         }
339
340         ms_batch_commit_enable(false, 0);
341         ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
342         ms_batch_commit_disable(scan_data->uid);
343
344         if (ms_delete_invalid_items(handle, scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
345                 MS_DBG_ERR("deleting invalid items in storage failed");
346
347         if (ms_delete_invalid_folder(scan_data->storage_id, scan_data->uid) != MS_MEDIA_ERR_NONE)
348                 MS_DBG_ERR("deleting invalid folders in storage failed");
349
350         ms_disconnect_db(handle);
351
352         return ret;
353 }
354
355 static int __msc_storage_scan_all(ms_comm_msg_s *scan_data, ms_user_storage_type_e storage_type)
356 {
357         int ret = MS_MEDIA_ERR_NONE;
358         sqlite3 *handle = NULL;
359
360         ret = ms_connect_db(&handle, scan_data->uid);
361         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_connect_db failed");
362
363         ms_set_db_status(MS_DB_UPDATING, storage_type);
364
365         ms_batch_commit_enable(false, 0);
366         ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
367         ms_batch_commit_disable(scan_data->uid);
368
369         ms_disconnect_db(handle);
370
371         return ret;
372 }
373
374 gpointer msc_storage_scan_thread(gpointer data)
375 {
376         int ret = MS_MEDIA_ERR_NONE;
377         ms_comm_msg_s *scan_data = NULL;
378         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
379
380         while (1) {
381                 scan_data = g_async_queue_pop(storage_queue);
382                 if (scan_data->pid == POWEROFF) {
383                         MS_DBG_WARN("power off");
384                         goto _POWEROFF;
385                 }
386
387                 MS_DBG_WARN("STORAGE SCAN START [%.*s][%s]", MAX_MSG_SIZE, scan_data->msg, scan_data->storage_id);
388
389                 if (strlen(scan_data->storage_id) == 0) {
390                         MS_DBG_ERR("storage_id length is 0");
391                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
392                         goto NEXT;
393                 }
394
395                 ret = ms_user_get_storage_type(scan_data->uid, scan_data->msg, &storage_type);
396                 if (ret != MS_MEDIA_ERR_NONE) {
397                         MS_DBG_ERR("ms_user_get_storage_type failed");
398                         goto NEXT;
399                 }
400
401                 if (scan_data->msg_type == MS_MSG_STORAGE_PARTIAL) {
402                         ret = __msc_storage_scan_partial(scan_data, storage_type);
403                 } else if (scan_data->msg_type == MS_MSG_STORAGE_ALL || scan_data->msg_type == MS_MSG_STORAGE_INVALID) {
404                         ret = __msc_storage_scan_all(scan_data, storage_type);
405                 } else {
406                         MS_DBG_ERR("Invalid request[%d]", scan_data->msg_type);
407                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
408                         goto NEXT;
409                 }
410
411                 /* send notification */
412                 ms_send_dir_update_noti(scan_data->msg, NULL, MS_ITEM_UPDATE, scan_data->pid);
413
414                 if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP)
415                         ms_set_db_status(MS_DB_STOPPED, storage_type);
416                 else
417                         ms_set_db_status(MS_DB_UPDATED, storage_type);
418 NEXT:
419                 if (__msc_is_power_off())
420                         goto _POWEROFF;
421
422                 /*Active flush */
423                 malloc_trim(0);
424
425                 msc_send_result(ret, scan_data);
426                 g_free(scan_data);
427
428                 MS_DBG_WARN("STORAGE SCAN END[%d]", ret);
429         }                       /*thread while*/
430 _POWEROFF:
431         g_free(scan_data);
432
433         return NULL;
434 }
435
436 static int __msc_make_file_list(char *file_path, GPtrArray **path_array, uid_t uid)
437 {
438         FILE *fp = NULL;
439         char buf[MS_FILE_PATH_LEN_MAX] = {0, };
440         char *path = NULL;
441         int length;
442         GPtrArray *_path_array = NULL;
443         int ret = MS_MEDIA_ERR_NONE;
444
445         fp = fopen(file_path, "rt");
446         MS_DBG_RETVM_IF(!fp, MS_MEDIA_ERR_INTERNAL, "fopen failed");
447
448         _path_array = g_ptr_array_new_with_free_func(g_free);
449
450         while (fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) {
451                 /* Remove '\n' */
452                 length = strlen(buf);
453                 path = g_strndup(buf, length - 1);
454
455                 /* check valid path */
456                 ret = ms_check_ignore_dir(path, uid);
457                 if (ret != MS_MEDIA_ERR_NONE) {
458                         MS_DBG_SERR("invalide path : %s", path);
459                         g_free(path);
460                         continue;
461                 }
462
463                 g_ptr_array_add(_path_array, path);
464         }
465
466         if (fp) fclose(fp);
467
468         *path_array = _path_array;
469
470         return MS_MEDIA_ERR_NONE;
471 }
472
473 static int __msc_batch_insert(int pid, GPtrArray *path_array, uid_t uid)
474 {
475         int ret = MS_MEDIA_ERR_NONE;
476         sqlite3 *handle = NULL;
477         char *insert_path = NULL;
478         char storage_id[MS_UUID_SIZE] = {0,};
479         int i = 0;
480
481         MS_DBG_FENTER();
482
483         ret = ms_connect_db(&handle, uid);
484         MS_DBG_RETV_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_DB_INTERNAL);
485
486         ms_batch_commit_enable(true, pid);
487
488         for (i = 0; i < path_array->len; i++) {
489                 insert_path = g_ptr_array_index(path_array, i);
490
491                 memset(storage_id, 0x0, MS_UUID_SIZE);
492                 if (ms_get_storage_id(handle, insert_path, storage_id, uid) != MS_MEDIA_ERR_NONE) {
493                         MS_DBG_ERR("There is no storage id in media db");
494                         continue;
495                 }
496
497                 ret = ms_insert_item_batch(handle, storage_id, insert_path, uid);
498
499                 if (__msc_is_power_off()) {
500                         ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
501                         break;
502                 }
503         }
504
505         /*call for bundle commit*/
506         ms_batch_commit_disable(uid);
507         ms_disconnect_db(handle);
508
509         MS_DBG_FLEAVE();
510
511         return ret;
512 }
513
514 gpointer msc_register_thread(gpointer data)
515 {
516         int ret = MS_MEDIA_ERR_NONE;
517         ms_comm_msg_s *register_data = NULL;
518         GPtrArray *path_array = NULL;
519
520         while (1) {
521                 register_data = g_async_queue_pop(reg_queue);
522
523                 if (register_data->pid == POWEROFF) {
524                         MS_DBG_ERR("power off");
525                         g_free(register_data);
526                         return NULL;
527                 }
528
529                 if (register_data->msg_type == MS_MSG_BULK_INSERT) {
530                         ret = __msc_make_file_list(register_data->msg, &path_array, register_data->uid);
531                         if (ret == MS_MEDIA_ERR_NONE) {
532                                 MS_DBG_SLOG("BULK REGISTER START [%.*s]", MAX_MSG_SIZE, register_data->msg);
533                                 ret = __msc_batch_insert(register_data->pid, path_array, register_data->uid);
534                                 g_ptr_array_free(path_array, TRUE);
535                                 path_array = NULL;
536                                 MS_DBG_WARN("BULK REGISTER END [%d]", ret);
537                         } else {
538                                 MS_DBG_ERR("__msc_make_file_list failed [%d]", ret);
539                         }
540                 } else {
541
542                         MS_DBG_ERR("invalid message type [%d]", register_data->msg_type);
543                         ret = MS_MEDIA_ERR_INVALID_PARAMETER;
544                 }
545
546                 /*Active flush */
547                 malloc_trim(0);
548
549                 msc_send_result(ret, register_data);
550                 g_free(register_data);
551         }                       /*thread while*/
552
553         return NULL;
554 }
555
556 static gpointer __msc_metadata_update_thread(gpointer data)
557 {
558         ms_comm_msg_s *scan_data = data;
559         int ret = MS_MEDIA_ERR_NONE;
560         sqlite3 *handle = NULL;
561
562         ret = ms_connect_db(&handle, scan_data->uid);
563         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, NULL, "ms_connect_db failed");
564
565         MS_DBG_INFO("META UPDATE START");
566
567         ret = ms_update_meta_batch(handle, scan_data->uid);
568         ms_disconnect_db(handle);
569
570         msc_send_result(ret, scan_data);
571         g_free(scan_data);
572
573         MS_DBG_INFO("META UPDATE END [%d]", ret);
574
575         return NULL;
576 }
577
578 void msc_metadata_update_thread(ms_comm_msg_s *recv_msg)
579 {
580         GThread *update_thread = g_thread_new("metadata_update_thread", __msc_metadata_update_thread, recv_msg);
581         g_thread_join(update_thread);
582 }
583
584 void msc_init_scanner(void)
585 {
586         if (!scan_queue) scan_queue = g_async_queue_new();
587         if (!reg_queue) reg_queue = g_async_queue_new();
588         if (!storage_queue) storage_queue = g_async_queue_new();
589
590         /*Init mutex variable*/
591         g_mutex_init(&scan_req_mutex);
592
593 }
594
595 void msc_deinit_scanner(void)
596 {
597         if (scan_queue) g_async_queue_unref(scan_queue);
598         if (reg_queue) g_async_queue_unref(reg_queue);
599         if (storage_queue) g_async_queue_unref(storage_queue);
600
601         /*Clear db mutex variable*/
602         g_mutex_clear(&scan_req_mutex);
603
604 }
605
606 int msc_push_scan_request(ms_scan_type_e scan_type, ms_comm_msg_s *recv_msg)
607 {
608         int ret = MS_MEDIA_ERR_NONE;
609
610         switch (scan_type) {
611         case MS_SCAN_STORAGE:
612                 g_async_queue_push(storage_queue, recv_msg);
613                 break;
614         case MS_SCAN_DIRECTORY:
615                 g_async_queue_push(scan_queue, recv_msg);
616                 break;
617         case MS_SCAN_REGISTER:
618                 g_async_queue_push(reg_queue, recv_msg);
619                 break;
620         default:
621                 MS_DBG_ERR("invalid parameter");
622                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
623                 break;
624         }
625
626         return ret;
627 }
628
629 void msc_send_power_off_request(void)
630 {
631         ms_comm_msg_s *data = NULL;
632
633         power_off = true;
634
635         if (scan_queue) {
636                 /*notify to scannig thread*/
637                 data = g_new0(ms_comm_msg_s, 1);
638
639                 data->pid = POWEROFF;
640                 msc_push_scan_request(MS_SCAN_DIRECTORY, data);
641         }
642
643         if (reg_queue) {
644                 /*notify to register thread*/
645                 data = g_new0(ms_comm_msg_s, 1);
646
647                 data->pid = POWEROFF;
648                 msc_push_scan_request(MS_SCAN_REGISTER, data);
649         }
650
651         if (storage_queue) {
652                 /*notify to register thread*/
653                 data = g_new0(ms_comm_msg_s, 1);
654
655                 data->pid = POWEROFF;
656                 msc_push_scan_request(MS_SCAN_STORAGE, data);
657         }
658 }
659
660 void msc_remove_dir_scan_request(ms_comm_msg_s *recv_msg)
661 {
662         int i = 0;
663         ms_comm_msg_s *msg = NULL;
664         GAsyncQueue *temp_scan_queue = NULL;
665         int queue_len = g_async_queue_length(scan_queue);
666
667         if (queue_len == 0) {
668                 MS_DBG_ERR("Request is not stacked");
669                 return;
670         }
671
672         MS_DBG_WARN("scan_req_mutex is LOCKED");
673         g_mutex_lock(&scan_req_mutex);
674
675         temp_scan_queue = g_async_queue_new();
676
677         for (i = 0; i < queue_len; i++) {
678                 /*create new queue to compare request*/
679                 msg = g_async_queue_pop(scan_queue);
680                 if ((g_strcmp0(msg->msg, recv_msg->msg) == 0) && (recv_msg->pid == msg->pid)) {
681                         MS_DBG("Find request. Remove it");
682                         g_free(msg);
683                 } else {
684                         g_async_queue_push(temp_scan_queue, msg);
685                 }
686         }
687         g_async_queue_unref(scan_queue);
688         scan_queue = temp_scan_queue;
689
690         g_mutex_unlock(&scan_req_mutex);
691         MS_DBG_WARN("scan_req_mutex is UNLOCKED");
692 }