8e801956f8ca787d34379c5b4b9581bc89bdc34c
[apps/home/gallery.git] / libug / libug-gallery-efl / src / ge-db-handler.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.tizenopensource.org/license
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17 #include <media-svc.h>
18 #include <visual-svc.h>
19 #include "ge-db-handler.h"
20 #include "ge-debug.h"
21 #include "ge-util.h"
22 #include "ge-strings.h"
23
24 static int ge_all_count = 0;
25 static Eina_List* ge_db_item_list = NULL;
26 static Eina_List* ge_item_selected_list = NULL;
27
28 #define ALBUM_ALL_LEN 4
29 #define GE_DB_FILE_LEN_MAX 1024
30
31 static int _ge_db_elist_ite_fn(Mitem *item, void *user_data)
32 {
33         Eina_List **list = (Eina_List **)user_data;
34         *list = eina_list_append(*list, item);
35         return GE_DB_SUCCESS;
36 }
37
38 static int _ge_db_cluster_elist_ite_fn(Mcluster *cluster, void *user_data)
39 {
40         Eina_List **list = (Eina_List **)user_data;
41         *list = eina_list_append(*list, cluster);
42         return GE_DB_SUCCESS;
43 }
44
45 /*
46 *  create a gitem
47 */
48 static ge_item* _ge_db_new_item(void)
49 {
50         ge_item* gitem = (ge_item*)calloc(1, sizeof(ge_item));
51         GE_CHECK_NULL(gitem);
52         return gitem;
53 }
54
55 /*
56 *   destroy a ge_item
57 */
58 static int _ge_db_destroy_item(ge_item* gitem)
59 {
60         if(gitem)
61         {
62                 if(gitem->item)
63                 {
64                         ge_db_destroy_mtype_item(gitem->item);
65                         gitem->item = NULL;
66                 }
67
68                 if(gitem->_reserved)
69                 {
70                         free(gitem->_reserved);
71                         gitem->_reserved = NULL;
72                 }
73
74                 gitem->elm_item = NULL;
75                 gitem->checked = false;
76                 gitem->check_obj = NULL;
77                 free(gitem);
78                 gitem = NULL;
79         }
80         return GE_DB_SUCCESS;
81 }
82
83 static int _ge_db_clear_mtype_items_list(Eina_List **elist)
84 {
85         void *current = NULL;
86
87         if (elist && *elist) {
88                 ge_dbg("Clear Mitems list.");
89                 EINA_LIST_FREE(*elist, current) {
90                         if (current) {
91                                 ge_db_destroy_mtype_item(current);
92                                 current = NULL;
93                         }
94                 }
95
96                 *elist = NULL;
97         }
98
99         return GE_DB_SUCCESS;
100 }
101
102 static int _ge_db_clear_items_list(void)
103 {
104         ge_item* current = NULL;
105
106         if (ge_db_item_list)
107         {
108                 ge_dbg("Clear items list.");
109                 EINA_LIST_FREE(ge_db_item_list, current)
110                 {
111                         _ge_db_destroy_item(current);
112                         current = NULL;
113                 }
114         }
115         ge_db_item_list = NULL;
116         ge_all_count = 0;
117         return GE_DB_SUCCESS;
118 }
119
120 static int _ge_db_free_cluster(ge_cluster* gcluster)
121 {
122         GE_CHECK_VAL(gcluster, GE_DB_FAIL);
123         if(gcluster->cluster)
124         {
125                 ge_db_destroy_mtype_item(gcluster->cluster);
126                 gcluster->cluster = NULL;
127         }
128         if(gcluster->_reserved)
129         {
130                 free(gcluster->_reserved);
131                 gcluster->_reserved = NULL;
132         }
133         free(gcluster);
134         return GE_DB_SUCCESS;
135 }
136
137 /* Free memory allocated for 'All' album */
138 static int _ge_db_free_cluster_all(ge_cluster* gcluster)
139 {
140         GE_CHECK_VAL(gcluster, GE_DB_FAIL);
141         GE_CHECK_VAL(gcluster->cluster, GE_DB_FAIL);
142
143         if(gcluster->cluster->display_name)
144         {
145                 free(gcluster->cluster->display_name);
146                 gcluster->cluster->display_name = NULL;
147         }
148
149         if(gcluster->_reserved)
150         {
151                 free(gcluster->_reserved);
152                 gcluster->_reserved = NULL;
153         }
154
155         free(gcluster->cluster);
156         gcluster->cluster = NULL;
157         free(gcluster);
158         return GE_DB_SUCCESS;
159 }
160
161 static int _ge_db_clear_clusters_list(ge_ugdata* ugd)
162 {
163         GE_CHECK_VAL(ugd, GE_DB_FAIL);
164         ge_cluster* current = NULL;
165         Eina_List* tmp_list = NULL;
166
167         _ge_set_current_album(NULL);
168
169         if(ugd->cluster_list)
170         {
171                 if(ugd->cluster_list->clist)
172                 {
173                         ge_dbg("Clear clusters list.");
174                         tmp_list = ugd->cluster_list->clist;
175                         EINA_LIST_FREE(tmp_list, current)
176                         {
177                                 if(current)
178                                 {
179                                         if(current->cluster &&
180                                            current->cluster->uuid &&
181                                            !g_strcmp0(current->cluster->uuid, GE_ALBUM_ALL_ID))
182                                         {
183                                                 _ge_db_free_cluster_all(current);
184                                         }
185                                         else
186                                         {
187                                                 _ge_db_free_cluster(current);
188                                         }
189                                 }
190                                 current = NULL;
191                         }
192                         ugd->cluster_list->clist = NULL;
193                 }
194
195                 free(ugd->cluster_list);
196                 ugd->cluster_list = NULL;
197         }
198
199         return GE_DB_SUCCESS;
200 }
201
202 static ge_cluster_list* _ge_db_new_clusters_list(void)
203 {
204         ge_cluster_list* clus_list = (ge_cluster_list*)calloc(1, sizeof(ge_cluster_list));
205         GE_CHECK_NULL(clus_list);
206         return clus_list;
207 }
208
209 static ge_cluster* _ge_db_new_cluster(void)
210 {
211         ge_cluster* gcluster = (ge_cluster*)calloc(1, sizeof(ge_cluster));
212         GE_CHECK_NULL(gcluster);
213         return gcluster;
214 }
215
216 /* Create 'All' album */
217 static ge_cluster* _ge_db_new_cluster_all(ge_ugdata* ugd, int count)
218 {
219         GE_CHECK_NULL(ugd);
220         ge_cluster* gcluster = _ge_db_new_cluster();
221         GE_CHECK_NULL(gcluster);
222
223         /* Pass -1 to get a mcluster from libmedia-info, not a real record in DB */
224         Mcluster* cluster = ge_db_new_mcluster(ugd, NULL);
225         if(cluster == NULL)
226         {
227                 free(gcluster);
228                 gcluster = NULL;
229                 return NULL;
230         }
231
232         cluster->uuid = strdup(GE_ALBUM_ALL_ID);
233         cluster->display_name = strdup(GE_ALBUM_ALL_NAME);
234         cluster->count = count;
235         gcluster->cluster = cluster;
236         gcluster->ugd = ugd;
237         gcluster->index = 0;
238
239         return gcluster;
240 }
241
242 /* Case 1: Carema shot[0], All[1], ...; Case 2: All[0], ... */
243 static int _ge_db_get_clusters_list(ge_ugdata* ugd)
244 {
245         GE_CHECK_VAL(ugd, -1);
246         int length = 0;
247         int local_item_cnt = 0;
248         Eina_List *item_list = NULL;
249         Mcluster *f_data = NULL;
250         ge_cluster * default_cluster = NULL;
251         ge_cluster* gcluster = NULL;
252         int medias_cnt = 0;
253         int err = -1;
254         minfo_cluster_filter filter;
255         minfo_item_filter item_filter;
256
257         /* Get real albums */
258         memset(&filter, 0x00, sizeof(minfo_cluster_filter));
259         filter.cluster_type = MINFO_CLUSTER_TYPE_ALL;
260         filter.sort_type = MINFO_CLUSTER_SORT_BY_NAME_ASC;
261         filter.start_pos = GE_GET_ALL_RECORDS;
262         filter.end_pos = GE_GET_ALL_RECORDS;
263
264         err = minfo_get_cluster_list(ugd->db_handle, filter,
265                                         _ge_db_cluster_elist_ite_fn, &item_list);
266         if(err == MB_SVC_ERROR_DB_NO_RECORD) {
267                 ge_dbgE("No record");
268                 if (item_list)
269                         _ge_db_clear_mtype_items_list(&item_list);
270                 return err;
271         } else if(err != 0) {
272                 ge_dbgE("minfo_get_cluster_list failed(%d)!", err);
273                 if (item_list)
274                         _ge_db_clear_mtype_items_list(&item_list);
275                 return err;
276         }
277
278         Eina_List* clist = ugd->cluster_list->clist;
279
280         EINA_LIST_FREE(item_list, f_data) {
281                 if (f_data == NULL || f_data->uuid == NULL) {
282                         /* Invalid data, next one */
283                         ge_dbgE("Invalid Mcluster!");
284                         continue;
285                 }
286                 ge_dbg("Cluster ID: %s.", f_data->uuid);
287
288                 /* only image is valid in setas mode. */
289                 if (ugd->file_type_mode == GE_File_Select_Type_Image ||
290                     ugd->file_type_mode == GE_File_Select_Type_Video) {
291                         memset(&item_filter,0x00,sizeof(minfo_item_filter));
292                         if(ugd->file_type_mode == GE_File_Select_Type_Image)
293                                 item_filter.file_type = MINFO_ITEM_IMAGE;
294                         else
295                                 item_filter.file_type = MINFO_ITEM_VIDEO;
296                         item_filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
297                         item_filter.start_pos = GE_GET_ALL_RECORDS;
298                         item_filter.end_pos = GE_GET_ALL_RECORDS;
299                         item_filter.with_meta = false;
300
301                         err = minfo_get_item_cnt(ugd->db_handle, f_data->uuid,
302                                                 item_filter, &medias_cnt);
303                         if(err == 0 || err == MB_SVC_ERROR_DB_NO_RECORD) {
304                                 f_data->count = medias_cnt;
305                         } else {
306                                 ge_dbgW("minfo_get_cluster_cnt[err:%d]", err);
307                                 f_data->count = 0;
308                         }
309                 }
310
311                 if(f_data->count == 0) {
312                         /* Skip empty album, next one */
313                         ge_dbgW("local album is empty, skipping it.");
314                         ge_db_destroy_mtype_item(f_data);
315                         continue;
316                 }
317
318                 gcluster = _ge_db_new_cluster();
319                 if(gcluster == NULL) {
320                         ge_dbgE("_ge_db_new_cluster failed!");
321                         ge_db_destroy_mtype_item(f_data);
322                         continue;
323                 }
324
325                 gcluster->cluster = f_data;
326                 gcluster->ugd = ugd;
327                 length += f_data->count;
328                 local_item_cnt += f_data->count;
329
330                 if (ge_db_is_default_album(ugd, f_data)) {
331                         /**
332                         * Default album: Camera Shot
333                         * Now Camera Shot is located in Phone.
334                         * If user can determine the location of default album,
335                         * here we should get the path and check it's in Phone or MMC.
336                         */
337                         default_cluster = gcluster;
338                         clist = eina_list_prepend(clist, gcluster);
339                 } else {
340                         clist = eina_list_append(clist, gcluster);
341                 }
342                 ugd->cluster_list->clist = clist;
343         }
344         ge_dbg("Get local clusters list Done!");
345         if(local_item_cnt) {
346                 /* Create "All" album if any file exists */
347                 gcluster = _ge_db_new_cluster_all(ugd, local_item_cnt);
348                 GE_CHECK_VAL(gcluster, -1);
349
350                 if(default_cluster)
351                         clist = eina_list_append_relative(clist, gcluster,
352                                                           default_cluster);
353                 else
354                         clist= eina_list_prepend(clist, gcluster);
355
356                 ugd->cluster_list->clist = clist;
357                 ge_dbg("Cluster All added!");
358         }
359
360         return length;
361 }
362
363 static int _ge_db_get_selected_item_id_list(Eina_List **sel_id_list)
364 {
365         GE_CHECK_VAL(sel_id_list, -1);
366         GE_CHECK_VAL(ge_item_selected_list, -1);
367         ge_item *gitem = NULL;
368         char *item_id = NULL;
369
370         /* Save ID of selected items */
371         EINA_LIST_FREE(ge_item_selected_list, gitem) {
372                 if (gitem && gitem->item && gitem->item->uuid) {
373                         item_id = strdup(gitem->item->uuid);
374                         *sel_id_list = eina_list_append(*sel_id_list,
375                                                         (void *)item_id);
376                 }
377         }
378
379         ge_db_selected_list_finalize();
380         return 0;
381 }
382
383 /* Free list of selected IDs */
384 static int __ge_db_free_selected_id_list(Eina_List **sel_id_list)
385 {
386         GE_CHECK_VAL(sel_id_list, -1);
387         if (*sel_id_list == NULL) {
388                 ge_dbg("sel_id_list is empty!");
389                 return -1;
390         }
391
392         void *p_id = NULL;
393         EINA_LIST_FREE(*sel_id_list, p_id) {
394                 if (p_id == NULL) {
395                         ge_dbgE("Invalid p_id!");
396                         continue;
397                 }
398                 free(p_id);
399                 p_id = NULL;
400         }
401         *sel_id_list = NULL;
402         return 0;
403 }
404
405 /* Check ID is in the list or not */
406 static bool _ge_db_check_selected_id(Eina_List **sel_id_list, const char *id)
407 {
408         GE_CHECK_FALSE(sel_id_list);
409         GE_CHECK_FALSE(id);
410         Eina_List *tmp_elist = NULL;
411         void *p_id = NULL;
412
413         if (eina_list_count(*sel_id_list) == 0) {
414                 ge_dbgE("sel_id_list is empty!");
415                 return false;
416         }
417
418         EINA_LIST_FOREACH(*sel_id_list, tmp_elist, p_id) {
419                 if (p_id == NULL) {
420                         ge_dbgE("Invalid p_id!");
421                         continue;
422                 }
423                 if (g_strcmp0(id, p_id)) {
424                         p_id = NULL;
425                         continue;
426                 }
427
428                 *sel_id_list = eina_list_remove(*sel_id_list, p_id);
429                 free(p_id);
430                 p_id = NULL;
431                 return true;
432         }
433         return false;
434 }
435
436 /*
437 *   get a new cluster from media service by cluster id
438 */
439 Mcluster* ge_db_new_mcluster(ge_ugdata* ugd, const char *cluster_id)
440 {
441         GE_CHECK_NULL(ugd);
442         Mcluster* mcluster = NULL;
443         int ret = minfo_get_cluster(ugd->db_handle, NULL, cluster_id, &mcluster);
444         if(ret != 0)
445         {
446                 ge_dbgE("minfo_get_cluster failed(%d)!", ret);
447                 return NULL;
448         }
449
450         return mcluster;
451 }
452 /*
453 *  get a new item from media service by item id
454 */
455 Mitem* ge_db_new_mitem(ge_ugdata* ugd, const char *item_id)
456 {
457         GE_CHECK_NULL(ugd);
458         Mitem* mitem = NULL;
459         /*new API, to use media id to get item.  */
460         int ret = minfo_get_item_by_id(ugd->db_handle, item_id, &mitem);
461         if(ret != 0)
462         {
463                 ge_dbgE("minfo_get_item_by_id failed(%d)!", ret);
464                 return NULL;
465         }
466
467         return mitem;
468 }
469
470 int ge_db_update_items_cnt(ge_ugdata* ugd, ge_cluster *album)
471 {
472         GE_CHECK_VAL(album, GE_DB_FAIL);
473         GE_CHECK_VAL(album->cluster, GE_DB_FAIL);
474         GE_CHECK_VAL(album->cluster->uuid, GE_DB_FAIL);
475         GE_CHECK_VAL(ugd, GE_DB_FAIL);
476         minfo_item_filter filter;
477         int err = -1;
478         int item_count = 0;
479
480         memset(&filter,0x00,sizeof(minfo_item_filter));
481         if(ugd->file_type_mode == GE_File_Select_Type_Image)
482         {
483                 filter.file_type = MINFO_ITEM_IMAGE;
484         }
485         else if(ugd->file_type_mode == GE_File_Select_Type_Video)
486         {
487                 filter.file_type = MINFO_ITEM_VIDEO;
488         }
489         else
490         {
491                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
492         }
493         filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
494         filter.start_pos = GE_GET_ALL_RECORDS;
495         filter.end_pos = GE_GET_ALL_RECORDS;
496         filter.with_meta = false;
497
498         if(g_strcmp0(album->cluster->uuid, GE_ALBUM_ALL_ID)) {
499                 /* real album */
500                 err = minfo_get_item_cnt(ugd->db_handle, album->cluster->uuid,
501                                                 filter, &item_count);
502                 if(err < 0)
503                 {
504                         ge_dbg("minfo_get_item_cnt failed(%d)!", err);
505                         return GE_DB_FAIL;
506                 }
507         }
508         else// "All" album
509         {
510                 ge_dbg("all media count");
511                 /**
512                 * Fixme: Use better API.
513                 * No way to set filter if call minfo_get_all_item_cnt to get all count,
514                 * So get item list firstly, then get all items count.
515                 */
516                 Eina_List* itemlist = NULL;
517                 err = minfo_get_all_item_list(ugd->db_handle,
518                                                         MINFO_CLUSTER_TYPE_LOCAL_ALL,
519                                                         filter, _ge_db_elist_ite_fn,
520                                                         &itemlist);
521
522                 if(err < 0 || itemlist == NULL) {
523                         ge_dbg("minfo_get_all_item_list failed(%d)!", err);
524                         if (itemlist)
525                                 _ge_db_clear_mtype_items_list(&itemlist);
526                         return GE_DB_FAIL;
527                 }
528
529                 Mitem *item = NULL;
530                 EINA_LIST_FREE(itemlist, item) {
531                         if (item) {
532                                 item_count++;
533                                 ge_db_destroy_mtype_item(item);
534                                 item = NULL;
535                         }
536                 }
537         }
538
539         ge_dbg("cluster media count : old=%d, new=%d", album->cluster->count, item_count);
540         album->cluster->count = item_count;
541
542         return GE_DB_SUCCESS;
543 }
544
545 int ge_db_get_clusters_list(ge_ugdata* ugd)
546 {
547         GE_CHECK_VAL(ugd, GE_DB_FAIL);
548         int n_entire_items = 0;
549
550         _ge_db_clear_clusters_list(ugd);
551
552         ugd->cluster_list = _ge_db_new_clusters_list();
553         n_entire_items = _ge_db_get_clusters_list(ugd);
554         ge_dbg("Total media items count:%d", n_entire_items);
555         if(n_entire_items <= 0)//if error code is returned, negative value is possible
556         {
557                 return GE_DB_FAIL;
558         }
559
560         return GE_DB_SUCCESS;
561 }
562
563 /* Clear items list */
564 int ge_db_clear_items_list(void)
565 {
566         return _ge_db_clear_items_list();
567 }
568
569 int ge_db_get_items_list(ge_ugdata* ugd, ge_cluster *album, int start_pos, int end_pos)
570 {
571         GE_CHECK_VAL(album, GE_DB_FAIL);
572         GE_CHECK_VAL(album->cluster, GE_DB_FAIL);
573         GE_CHECK_VAL(album->cluster->uuid, GE_DB_FAIL);
574         GE_CHECK_VAL(ugd, -1);
575         Eina_List* itemlist = NULL;
576         minfo_item_filter filter;
577         int err = -1;
578
579         ge_dbg("--start_pos[%d], end_pos[%d]--", start_pos, end_pos);
580         memset(&filter,0x00,sizeof(minfo_item_filter));
581         if(ugd->file_type_mode == GE_File_Select_Type_Image)
582         {
583                 filter.file_type = MINFO_ITEM_IMAGE;
584         }
585         else if(ugd->file_type_mode == GE_File_Select_Type_Video)
586         {
587                 filter.file_type = MINFO_ITEM_VIDEO;
588         }
589         else
590         {
591                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
592         }
593         filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
594         filter.start_pos = start_pos;
595         filter.end_pos = end_pos;
596         filter.with_meta = true;
597
598         if(start_pos == (GE_FIRST_VIEW_END_POS+1) && end_pos == GE_GET_UNTIL_LAST_RECORD)
599         {
600                 /* Keep medias_elist and medias_cnt unchanged */
601                 ge_dbg("Gridview append idler; Keep ge_db_item_list unchanged.");
602         }
603         else
604         {
605                 /*Clear item list before new one got */
606                 _ge_db_clear_items_list();
607         }
608
609         if(g_strcmp0(album->cluster->uuid, GE_ALBUM_ALL_ID)) {
610                 /* real album */
611                 ge_dbg("--Real album--");
612                 err = minfo_get_item_list(ugd->db_handle, album->cluster->uuid,
613                                                 filter, _ge_db_elist_ite_fn, &itemlist);
614         }
615         else    //add "All" album
616         {
617                 ge_dbg("--Album All--");
618                 err = minfo_get_all_item_list(ugd->db_handle,
619                                                         MINFO_CLUSTER_TYPE_LOCAL_ALL,
620                                                         filter, _ge_db_elist_ite_fn,
621                                                         &itemlist);
622         }
623
624         if((err == 0) && (itemlist != NULL))
625         {
626                 Mitem *item = NULL;
627                 ge_item* gitem = NULL;
628                 EINA_LIST_FREE(itemlist, item)
629                 {
630                         if (item == NULL || item->uuid == NULL) {
631                                 ge_dbgE("Invalid item!");
632                                 continue;
633                         }
634
635                         gitem = _ge_db_new_item();
636                         if(gitem == NULL) {
637                                 ge_dbgE("_gl_db_new_item() failed");
638                                 ge_db_destroy_mtype_item(item);
639                                 continue;
640                         }
641
642                         gitem->item = item;
643                         gitem->ugd = ugd;
644                         ge_db_item_list = eina_list_append(ge_db_item_list, gitem);
645                         item = NULL;
646                         gitem = NULL;
647                 }
648
649                 ge_all_count = eina_list_count(ge_db_item_list);
650         }
651         else
652         {
653                 /* Free Mitems */
654                 if (itemlist)
655                         _ge_db_clear_mtype_items_list(&itemlist);
656
657                 if(start_pos == (GE_FIRST_VIEW_END_POS+1) && end_pos == GE_GET_UNTIL_LAST_RECORD)
658                 {
659                         /* Keep medias_elist and medias_cnt unchanged */
660                         ge_all_count = eina_list_count(ge_db_item_list);
661                         ge_dbg("Gridview append idler.");
662                 }
663                 else
664                 {
665                         ge_all_count = 0;
666                 }
667         }
668         ge_dbg("DB all count : %d, ge_db_item_list=%p", ge_all_count, ge_db_item_list);
669
670         return err;
671 }
672
673 /* Update items list, especially used in thumbnails edit view */
674 int ge_db_update_items_list(ge_ugdata* ugd, ge_cluster *album)
675 {
676         GE_CHECK_VAL(album, -1);
677         GE_CHECK_VAL(album->cluster, -1);
678         GE_CHECK_VAL(album->cluster->uuid, GE_DB_FAIL);
679         GE_CHECK_VAL(ugd, -1);
680         Eina_List* itemlist = NULL;
681         minfo_item_filter filter;
682         int err = -1;
683         ge_dbg("Update content of %s", album->cluster->display_name);
684         int view_mode = _ge_get_view_mode();
685         Eina_List *sel_id_list = NULL;
686
687         if (view_mode == GE_ThumbnailEdit_Mode &&
688             ugd->file_select_mode != GE_File_Select_One) {
689                 ge_dbg("Edit view for multiple selection.");
690                 /* Get ID list of selected items */
691                 _ge_db_get_selected_item_id_list(&sel_id_list);
692         }
693
694         memset(&filter,0x00,sizeof(minfo_item_filter));
695         if(ugd->file_type_mode == GE_File_Select_Type_Image)
696                 filter.file_type = MINFO_ITEM_IMAGE;
697         else if(ugd->file_type_mode == GE_File_Select_Type_Video)
698                 filter.file_type = MINFO_ITEM_VIDEO;
699         else
700                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
701         filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_DESC;
702         filter.start_pos = GE_GET_ALL_RECORDS;
703         filter.end_pos = GE_GET_ALL_RECORDS;
704         filter.with_meta = true;
705
706         /*Clear item list before new one got */
707         _ge_db_clear_items_list();
708
709         if(g_strcmp0(album->cluster->uuid, GE_ALBUM_ALL_ID))
710                 err = minfo_get_item_list(ugd->db_handle, album->cluster->uuid,
711                                                 filter, _ge_db_elist_ite_fn, &itemlist);
712         else
713                 err = minfo_get_all_item_list(ugd->db_handle,
714                                                         MINFO_CLUSTER_TYPE_LOCAL_ALL,
715                                                         filter, _ge_db_elist_ite_fn,
716                                                         &itemlist);
717
718         if ((err != 0) || (itemlist == NULL)) {
719                 ge_dbgE("(err != 0) || (itemlist == NULL)");
720                 /* Free Mitems */
721                 if (itemlist)
722                         _ge_db_clear_mtype_items_list(&itemlist);
723                 ge_all_count = 0;
724                 return err;
725         }
726
727         bool b_selected = false;
728         Mitem *item = NULL;
729         ge_item* gitem = NULL;
730         EINA_LIST_FREE(itemlist, item) {
731                 if (item == NULL || item->uuid == NULL) {
732                         ge_dbgE("Invalid item!");
733                         continue;
734                 }
735                 gitem = _ge_db_new_item();
736                 if(gitem == NULL) {
737                         ge_dbgE("_gl_db_new_item() failed");
738                         ge_db_destroy_mtype_item(item);
739                         continue;
740                 }
741
742                 gitem->item = item;
743                 gitem->ugd = ugd;
744                 ge_db_item_list = eina_list_append(ge_db_item_list, gitem);
745
746                 if (sel_id_list) {
747                         b_selected = _ge_db_check_selected_id(&sel_id_list,
748                                                               item->uuid);
749                         if (b_selected) {
750                                 b_selected = false;
751                                 /* Set checkbox state */
752                                 gitem->checked = true;
753                                 /* Append gitem to selected list */
754                                 ge_db_selected_list_append(gitem);
755                         }
756                 }
757
758                 item = NULL;
759                 gitem = NULL;
760         }
761
762         /* Clear list of selected ID */
763         if (sel_id_list)
764                 __ge_db_free_selected_id_list(&sel_id_list);
765
766         ge_all_count = eina_list_count(ge_db_item_list);
767         ge_dbg("DB all count : %d, ge_db_item_list=%p", ge_all_count,
768                ge_db_item_list);
769
770         return err;
771 }
772
773 int ge_db_get_first_several_items(ge_ugdata* ugd, ge_cluster *album,
774                                   ge_item* items[], int *item_count,
775                                   minfo_media_sort_type sort_type)
776 {
777         GE_CHECK_VAL(item_count, -1);
778         GE_CHECK_VAL(items, -1);
779         GE_CHECK_VAL(album, -1);
780         GE_CHECK_VAL(album->cluster, -1);
781         GE_CHECK_VAL(album->cluster->uuid, -1);
782         GE_CHECK_VAL(ugd, -1);
783         minfo_item_filter filter;
784         Eina_List *item_list = NULL;
785         int result_cnt = 0;
786         Mitem* item = NULL;
787         ge_item* gitem = NULL;
788         int err = -1;
789
790         if(*item_count <= 0)
791         {
792                 ge_dbgE("*item_count <= 0");
793                 return -1;
794         }
795         memset(&filter,0x00,sizeof(minfo_item_filter));
796         if(ugd->file_type_mode == GE_File_Select_Type_Image)
797         {
798                 filter.file_type = MINFO_ITEM_IMAGE;
799         }
800         else if(ugd->file_type_mode == GE_File_Select_Type_Video)
801         {
802                 filter.file_type = MINFO_ITEM_VIDEO;
803         }
804         else
805         {
806                 filter.file_type = MINFO_ITEM_IMAGE | MINFO_ITEM_VIDEO;
807         }
808         filter.sort_type = sort_type;
809         filter.start_pos = 0;
810         filter.end_pos = (*item_count == 1 ? 1 : (*item_count - 1));
811         filter.with_meta = false;
812
813         if(g_strcmp0(album->cluster->uuid, GE_ALBUM_ALL_ID)) {
814                 /*real album */
815                 err = minfo_get_item_list(ugd->db_handle, album->cluster->uuid,
816                                                 filter, _ge_db_elist_ite_fn, &item_list);
817                 if(err != 0 || item_list == NULL)
818                 {
819                         ge_dbgE("minfo_get_item_list failed(%d)", err);
820                         goto DB_FAILED;
821                 }
822         }
823         else    //add "All" album
824         {
825                 err = minfo_get_all_item_list(ugd->db_handle,
826                                                         MINFO_CLUSTER_TYPE_LOCAL_ALL,
827                                                         filter, _ge_db_elist_ite_fn,
828                                                         &item_list);
829                 if(err != 0 || item_list == NULL)
830                 {
831                         ge_dbgE("minfo_get_all_item_list failed(%d)", err);
832                         goto DB_FAILED;
833                 }
834         }
835
836         EINA_LIST_FREE(item_list, item) {
837                 if (item == NULL) {
838                         ge_dbgE("Invalid Mitem!");
839                         continue;
840                 }
841                 result_cnt++;
842                 if(result_cnt <= *item_count) {
843                         gitem = NULL;
844                         gitem = _ge_db_new_item();
845                         if (gitem == NULL) {
846                                 ge_dbgE("_ge_db_new_item failed!");
847                                 ge_db_destroy_mtype_item(item);
848                                 result_cnt--;
849                                 continue;
850                         }
851                         gitem->item = item;
852                         items[result_cnt-1] = gitem;
853                 } else {
854                         ge_db_destroy_mtype_item(item);
855                 }
856                 item = NULL;
857         }
858
859         if(*item_count > result_cnt)
860                 *item_count = result_cnt;
861
862         ge_dbg("First %d items of [%s]", *item_count, album->cluster->display_name);
863         return *item_count;
864
865  DB_FAILED:
866         *item_count = 0;
867         /* Free Mitems */
868         if (item_list)
869                 _ge_db_clear_mtype_items_list(&item_list);
870         return -1;
871 }
872
873 int ge_db_del_media_id(ge_ugdata* ugd, const char *media_id)
874 {
875         GE_CHECK_VAL(media_id, GE_DB_FAIL);
876         int ret = minfo_delete_media_id(ugd->db_handle, media_id);
877         if(ret != 0)
878         {
879                 ge_dbgE("minfo_delete_media_id failed(%d)!", ret);
880                 return GE_DB_FAIL;
881         }
882
883         return GE_DB_SUCCESS;
884 }
885
886 int ge_db_item_list_remove(ge_item* gitem)
887 {
888         GE_CHECK_VAL(gitem, GE_DB_FAIL);
889         GE_CHECK_VAL(gitem->item, GE_DB_FAIL);
890         GE_CHECK_VAL(gitem->item->uuid, GE_DB_FAIL);
891         ge_item* current = NULL;
892         Eina_List* l = NULL;
893
894         EINA_LIST_FOREACH(ge_db_item_list, l, current)
895         {
896
897                 if(current == NULL || current->item == NULL ||
898                    current->item->uuid == NULL) {
899                         ge_dbgE("Invalid gitem!");
900                         continue;
901                 }
902                 if(!g_strcmp0(current->item->uuid, gitem->item->uuid))
903                 {
904                         ge_db_item_list = eina_list_remove(ge_db_item_list, current);
905                         ge_all_count--;
906                         _ge_db_destroy_item(current);
907                         current = NULL;
908                         break;
909                 }
910         }
911         return GE_DB_SUCCESS;
912 }
913
914 int ge_db_destroy_mtype_item(void* item)
915 {
916         GE_CHECK_VAL(item, GE_DB_FAIL);
917         int ret = minfo_destroy_mtype_item(item);
918         if(ret != 0)
919         {
920                 ge_dbgE("minfo_destroy_mtype_item failed(%d)!", ret);
921                 return GE_DB_FAIL;
922         }
923
924         return GE_DB_SUCCESS;
925 }
926
927 int ge_db_destroy_item(ge_item * gitem)
928 {
929         GE_CHECK_VAL(gitem, GE_DB_FAIL);
930
931         _ge_db_destroy_item(gitem);
932         return GE_DB_SUCCESS;
933 }
934
935 int ge_db_get_item_by_index(ge_item** gitem, int idx)
936 {
937         GE_CHECK_VAL(gitem, GE_DB_FAIL);
938
939         if (idx > ge_all_count)
940         {
941             ge_dbg("db_get_item_by_index(%d) is failed\n", idx);
942                 *gitem = NULL;
943                 return GE_DB_FAIL;
944         }
945
946         *gitem = eina_list_nth(ge_db_item_list, idx -1);
947         return GE_DB_SUCCESS;
948 }
949
950 int ge_db_get_count_all(void)
951 {
952         return ge_all_count;
953 }
954
955 int ge_db_get_selected_item_by_index(ge_item** gitem, int idx)
956 {
957         GE_CHECK_VAL(gitem, GE_DB_FAIL);
958
959         if (idx > ge_db_selected_list_count())
960         {
961             ge_dbg("db_get_item_by_index(%d) is failed\n", idx);
962                 *gitem = NULL;
963                 return GE_DB_FAIL;
964         }
965
966         *gitem = eina_list_nth(ge_item_selected_list, idx -1);
967         return GE_DB_SUCCESS;
968 }
969
970 int ge_db_selected_list_count(void)
971 {
972         return eina_list_count(ge_item_selected_list);
973 }
974
975 Eina_List* ge_db_selected_list_get(void)
976 {
977         return ge_item_selected_list;
978 }
979
980 int ge_db_selected_list_append(ge_item* gitem)
981 {
982         GE_CHECK_VAL(gitem, GE_DB_FAIL);
983
984         ge_item_selected_list = eina_list_append(ge_item_selected_list, gitem);
985         return GE_DB_SUCCESS;
986 }
987
988 int ge_db_selected_list_remove(ge_item* gitem)
989 {
990         GE_CHECK_VAL(gitem, GE_DB_FAIL);
991         GE_CHECK_VAL(gitem->item, GE_DB_FAIL);
992         GE_CHECK_VAL(gitem->item->uuid, GE_DB_FAIL);
993         ge_item* current = NULL;
994         Eina_List* l = NULL;
995
996         EINA_LIST_FOREACH(ge_item_selected_list, l, current)
997         {
998                 if(current == NULL || current->item == NULL ||
999                    current->item->uuid == NULL) {
1000                         ge_dbgE("Invald gitem!");
1001                         continue;
1002                 }
1003                 if(!g_strcmp0(current->item->uuid, gitem->item->uuid))
1004                 {
1005                         ge_item_selected_list = eina_list_remove(ge_item_selected_list, current);
1006                         break;
1007                 }
1008         }
1009         return GE_DB_SUCCESS;
1010 }
1011
1012 int ge_db_selected_list_finalize(void)
1013 {
1014         ge_item* gitem = NULL;
1015
1016         EINA_LIST_FREE(ge_item_selected_list, gitem)
1017         {
1018                 if(gitem)
1019                 {
1020                         gitem->checked = false;
1021                 }
1022         }
1023
1024         ge_item_selected_list = NULL;
1025         return GE_DB_SUCCESS;
1026 }
1027
1028 /*
1029 *   get full path of cluster
1030 */
1031 int ge_db_get_folder_fullpath(ge_ugdata* ugd, const char *id, char *path)
1032 {
1033         GE_CHECK_VAL(ugd, GE_DB_FAIL);
1034         GE_CHECK_VAL(id, GE_DB_FAIL);
1035         GE_CHECK_VAL(path, GE_DB_FAIL);
1036         /*For safety, we should add one more parameter as a size of the output array. */
1037         return minfo_get_cluster_fullpath_by_id(ugd->db_handle,id, path,
1038                                                 GE_DIR_PATH_LEN_MAX);
1039 }
1040
1041 /*
1042 *   Check it's default album[Camera shot] or not
1043 */
1044 bool ge_db_is_default_album(ge_ugdata* ugd, Mcluster* mcluster)
1045 {
1046         GE_CHECK_VAL(ugd, GE_DB_FAIL);
1047         GE_CHECK_FALSE(mcluster);
1048         GE_CHECK_FALSE(mcluster->display_name);
1049         GE_CHECK_FALSE(mcluster->uuid);
1050         int ret = -1;
1051
1052         /* Name is 'Camera shot' and folder locates in Phone */
1053         ret = g_strcmp0(mcluster->display_name, GE_ALBUM_MY_NAME);
1054         if (ret == 0 && mcluster->type == MINFO_PHONE) {
1055                 char dir_path[GE_DIR_PATH_LEN_MAX] = { 0, };
1056                 int ret = minfo_get_cluster_fullpath_by_id(ugd->db_handle,
1057                                                                 mcluster->uuid,
1058                                                                 dir_path,
1059                                                                 GE_DIR_PATH_LEN_MAX);
1060                 if(ret != 0) {
1061                         ge_dbgE("get_cluster_fullpath_by_id failed[%d]!", ret);
1062                         return false;
1063                 }
1064                 ge_dbg("Full path: %s", dir_path);
1065                 /* Get parent directory */
1066                 char *parent_path = ecore_file_dir_get(dir_path);
1067                 GE_CHECK_FALSE(parent_path);
1068                 ge_dbg("Parent path: %s", parent_path);
1069
1070                 /* Parent directory is same as Phone root path, it's default folder */
1071                 ret = g_strcmp0(parent_path, GE_ROOT_PATH_PHONE);
1072                 GE_FREE_MEM(parent_path)
1073
1074                 if (ret == 0) {
1075                         ge_dbgW("Default folder!");
1076                         return true;
1077                 }
1078         }
1079
1080         return false;
1081 }
1082
1083 bool ge_db_is_root_path(ge_ugdata* ugd, const char *cluster_id, const char *path)
1084 {
1085         int res = 0;
1086         char dir_path[GE_DIR_PATH_LEN_MAX] = { 0, };
1087
1088         if(path) {
1089                 g_strlcpy(dir_path, path, GE_DIR_PATH_LEN_MAX);
1090         } else {
1091                 GE_CHECK_FALSE(cluster_id);
1092                 res = minfo_get_cluster_fullpath_by_id(ugd->db_handle,
1093                                                                 cluster_id, dir_path,
1094                                                                 GE_DIR_PATH_LEN_MAX);
1095                 if(res != 0) {
1096                         ge_dbgE("minfo_get_cluster_fullpath_by_id failed(%d)!", res);
1097                         return false;
1098                 }
1099         }
1100
1101         ge_dbg("Root path[/opt/media or /opt/storage/sdcard]: %s ?", dir_path);
1102         if(!g_strcmp0(GE_ROOT_PATH_PHONE, dir_path) ||
1103            !g_strcmp0(GE_ROOT_PATH_MMC, dir_path))
1104                 return true;
1105
1106         return false;
1107 }
1108
1109 int ge_db_init(ge_ugdata* ugd)
1110 {
1111         ge_dbg("Connect to libmedia-info!");
1112         GE_CHECK_VAL(ugd, GE_DB_FAIL);
1113         MediaSvcHandle *_db_handle = NULL;
1114
1115         int err = media_svc_connect(&_db_handle);
1116         if (err < 0) {
1117                 ge_dbgE("Connect to DB failed!");
1118                 return GE_DB_FAIL;
1119         }
1120
1121         ugd->db_handle = _db_handle;
1122         return GE_DB_SUCCESS;
1123 }
1124
1125 int ge_db_finalize(ge_ugdata* ugd)
1126 {
1127         ge_dbg("Free memory and disconnect with libmedia-info!");
1128         GE_CHECK_VAL(ugd, GE_DB_FAIL);
1129         _ge_db_clear_clusters_list(ugd);
1130         _ge_db_clear_items_list();
1131
1132         int err = media_svc_disconnect(ugd->db_handle);
1133         if (err != 0)
1134         {
1135                 ge_dbgE("\n\nDisconnect with libmedia-info failed!!!\n");
1136                 return GE_DB_FAIL;
1137         }
1138
1139         return GE_DB_SUCCESS;
1140 }
1141