82c8bcc038fe202bd89177a55d4b71ab2105b337
[apps/core/preloaded/gallery.git] / src / gallery.c
1 /*
2   * Copyright (c) 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://floralicense.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 <Evas.h>
18 #include <utilX.h> /* Key event */
19 #include "gallery.h"
20 #include "gl-debug.h"
21 #include "gl-albums.h"
22 #include "gl-thumbs.h"
23 #include "gl-controlbar.h"
24 #include "gl-ui-util.h"
25 #include "gl-lang.h"
26 #include "gl-util.h"
27 #include "gl-data.h"
28 #include "gl-ext-ug-load.h"
29 #include "gl-ext-exec.h"
30 #include "gl-tags.h"
31 #include "gl-popup.h"
32 #include "gl-ctxpopup.h"
33 #include "gl-progressbar.h"
34 #include "gl-editfield.h"
35 #include "gl-notify.h"
36 #include "gl-thread-util.h"
37 #include "gl-strings.h"
38
39 #define GL_BG_COLOR_R 248
40 #define GL_BG_COLOR_G 246
41 #define GL_BG_COLOR_B 239
42
43 #define GL_BD_LAUNCH_TYPE "launch-type"
44 #define GL_BD_ALBUM_ID "album-id"
45 #define GL_BD_FILE_TYPE "file-type"
46 #define GL_BD_DRM_TYPE "drm-type"
47 #define GL_BD_SETAS_TYPE "setas-type"
48 #define GL_BD_CALLERID_SIZE "callerid-size"
49 #define GL_BD_CALLERID_PATH "callerid-path"
50 #define GL_BD_HOMESCREEN_PATH "homescreen-path"
51 #define GL_BD_LOCKSCREEN_PATH "lockscreen-path"
52 #define GL_BD_SELECT_ALBUM "select-album"
53 #define GL_BD_SELECT_ONE "select-one"
54 #define GL_BD_SELECT_MULTIPLE "select-multiple"
55 #define GL_BD_SELECT_SETAS "select-setas"
56 #define GL_BD_FILE_TYPE_IMAGE "image"
57 #define GL_BD_FILE_TYPE_VIDEO "video"
58 #define GL_BD_FILE_TYPE_ALL "all"
59 #define GL_BD_SETAS_WALLPALER "wallpaper"
60 #define GL_BD_SETAS_CALLERID "callerid"
61 #define GL_BD_SHOW_DRM_FILE "true"
62
63 #define GL_BD_SELECTION_MODE "http://tizen.org/appcontrol/data/selection_mode"
64 #define GL_BD_SELECTION_MODE_SINGLE "single"
65 #define GL_BD_SELECTION_MODE_MULTI "multiple"
66
67 #define GL_AUL_SEP ":"
68 #define GL_SERVICE_OPERATION_WALLPAPER "http://tizen.org/appcontrol/operation/wallpaper"
69
70 struct text_part {
71         char *part;
72         char *msgid;
73 };
74
75 static struct text_part main_txt[] = {
76         {"txt_title", "Application template",},
77         {"txt_mesg", "Click to exit",},
78 };
79
80 /* User-defined function */
81 static int _gallery_init_app_svc(void *data);
82
83 static void _gallery_win_del_cb(void *data, Evas_Object *obj, void *event_info)
84 {
85         gl_dbgW("_gallery_win_del_cb!!");
86         GL_CHECK(data);
87
88         elm_exit();
89 }
90
91
92 static int _gallery_update_ts(Evas_Object *eo, struct text_part *tp, int size)
93 {
94         int i = 0;
95
96         if (eo == NULL || tp == NULL || size < 0) {
97                 return -1;
98         }
99         for (i = 0; i < size; i++) {
100                 if (tp[i].part && tp[i].msgid) {
101                         edje_object_part_text_set(eo, tp[i].part,
102                                                   tp[i].msgid);
103                 }
104         }
105
106         return 0;
107 }
108
109 static void _gallery_lang_changed_cb(void *data)
110 {
111         GL_CHECK(data);
112         gl_appdata *ad = (gl_appdata *)data;
113         GL_CHECK(ad->maininfo.main_layout);
114
115         _gallery_update_ts(elm_layout_edje_get(ad->maininfo.main_layout),
116                            main_txt, sizeof(main_txt) / sizeof(main_txt[0]));
117         _gl_lang_update(data);
118 }
119
120 static Eina_Bool __gallery_key_down_cb(void *data, int type, void *event)
121 {
122         if (!data) {
123                 gl_dbgE("Invalid parameter!");
124                 return ECORE_CALLBACK_PASS_ON;
125         }
126
127         gl_appdata *ad = (gl_appdata *)data;
128         ad->maininfo.home_key = false;
129         Ecore_Event_Key *key_event = (Ecore_Event_Key *)event;
130
131         if (!strcmp(key_event->keyname, KEY_END)) {
132                 gl_dbgW("Bakc(End) key");
133         } else if (!strcmp(key_event->keyname, KEY_SELECT)) {
134                 gl_dbgW("Home key");
135                 ad->maininfo.home_key = true;
136         } else if (!strcmp(key_event->keyname, KEY_POWER)) {
137                 gl_dbgW("Power key");
138         }
139
140         gl_dbg("Key down : %s", key_event->keyname);
141
142         return ECORE_CALLBACK_PASS_ON;
143 }
144
145 static void _gallery_low_battery_cb(void *data)
146 {
147         gl_dbg("");
148
149         /* ug_send_event(UG_EVENT_LOW_BATTERY); */
150         /* 0 : default handler, 1:user handler */
151 }
152
153 /**
154  * Perform an UI update according to the given rotation angle.
155  * Do not call elm_win_rotation_set / elm_win_rotation_with_resize_set.
156  * ecore_evas has already called
157  * elm_win_rotation_set / elm_win_rotation_with_resize_set function.
158  *
159  * Please set NULL to app_device_orientation_cb member of app_event_callback_s structure.
160  * And don't use app_device_orientation_cb callback which is supported by capi
161 */
162 static void __gallery_rot_changed_cb(void *data, Evas_Object *obj, void *event)
163 {
164         GL_CHECK(data);
165         gl_appdata *ad = (gl_appdata *)data;
166         GL_CHECK(ad->maininfo.win);
167         /* changed_ang value is 0 90 180 270 */
168         int changed_ang = elm_win_rotation_get(ad->maininfo.win);
169         gl_dbg("New angle: %d, old angle: %d", changed_ang,
170                ad->maininfo.rotate_mode);
171         if (changed_ang == ad->maininfo.rotate_mode)
172                 return;
173         else
174                 ad->maininfo.rotate_mode = changed_ang;
175
176         enum ug_event evt = UG_EVENT_NONE;
177         /* Send event to UG */
178         switch (changed_ang) {
179         case APP_DEVICE_ORIENTATION_0:
180                 evt = UG_EVENT_ROTATE_PORTRAIT;
181                 break;
182         case APP_DEVICE_ORIENTATION_90:
183                 evt = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
184                 break;
185         case APP_DEVICE_ORIENTATION_180:
186                 evt = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
187                 break;
188         case APP_DEVICE_ORIENTATION_270:
189                 evt = UG_EVENT_ROTATE_LANDSCAPE;
190                 break;
191         }
192         ug_send_event(evt);
193
194         int view_mode = gl_get_view_mode(ad);
195         if (ad->uginfo.ug_called_by_me) {
196                 if (view_mode == GL_VIEW_ALBUMS){
197                         gl_ctrl_rotate_ctrlbar(ad, GL_VIEW_NONE);
198                 }
199                 return;
200         }
201         gl_ctrl_rotate_ctrlbar(ad, GL_VIEW_NONE);
202 }
203
204 static Eina_Bool __gallery_prop_change(void *data, int ev_type, void *ev)
205 {
206         GL_CHECK_FALSE(ev);
207         Ecore_X_Event_Window_Property *event = ev;
208
209         if (event->win != ecore_x_window_root_first_get())
210                 return ECORE_CALLBACK_PASS_ON;
211
212         if (event->atom != ecore_x_atom_get("FONT_TYPE_change"))
213                 return ECORE_CALLBACK_PASS_ON;
214
215         gl_dbg("Font is changed!(FONT_TYPE_change)");
216         /* Remove ctxpopup */
217         _gl_ctxpopup_del(data);
218
219         return ECORE_CALLBACK_PASS_ON;
220 }
221
222 void profile_changed_cb(void *data, Evas_Object * obj, void *event)
223 {
224         const char *profile = elm_config_profile_get();
225
226         if (strcmp(profile, "desktop") == 0)
227                 elm_win_indicator_mode_set (obj, ELM_WIN_INDICATOR_HIDE);
228         else
229                 elm_win_indicator_mode_set (obj, ELM_WIN_INDICATOR_SHOW);
230 }
231
232 static Evas_Object *_gallery_create_win(void *data, const char *name)
233 {
234         gl_dbg_launch("  _gallery_create_win:start");
235         GL_CHECK_NULL(name);
236         GL_CHECK_NULL(data);
237         gl_appdata *ad = (gl_appdata *)data;
238         Evas_Object *eo = NULL;
239
240         gl_dbg_launch("    elm_win_add:start");
241         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
242         gl_dbg_launch("    elm_win_add:end");
243         if (eo) {
244                 /**
245                  * Register a list of rotation angles that your application supports
246                  *
247                  * The window manager is going to decide rotation of application windows
248                  * by referring the list of rotation angles.
249                  * In this means if your application sets 0, 90 and 270 degrees to be the list of
250                  * supported rotation angles, the window manager will not rotate your
251                  * application window if the device is rotated 180 degrees
252                  */
253                 if (elm_win_wm_rotation_supported_get(eo)) {
254                         const int rots[4] = { APP_DEVICE_ORIENTATION_0,
255                                               APP_DEVICE_ORIENTATION_90,
256                                               APP_DEVICE_ORIENTATION_180,
257                                               APP_DEVICE_ORIENTATION_270 };
258                         gl_dbg("");
259                         elm_win_wm_rotation_available_rotations_set(eo, rots, 4);
260                 }
261                 /* pass '-1' value to this API then it will unset preferred rotation angle */
262                 elm_win_wm_rotation_preferred_rotation_set(eo, -1);
263
264                 elm_win_autodel_set(eo, EINA_TRUE);
265                 elm_win_title_set(eo, name);
266                 evas_object_smart_callback_add(eo, "profile,changed",
267                                                profile_changed_cb, ad);
268                 evas_object_smart_callback_add(eo, "delete,request",
269                                                _gallery_win_del_cb, ad);
270                 evas_object_smart_callback_add(eo, "wm,rotation,changed",
271                                                __gallery_rot_changed_cb, data);
272                 ad->maininfo.win_scale = elm_config_scale_get();
273                 gl_dbg("main window scale: %f", ad->maininfo.win_scale);
274
275                 /*register x window property change callback */
276                 ecore_x_event_mask_set(ecore_x_window_root_first_get(),
277                                        ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
278
279                 ad->maininfo.font_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
280                                                                     __gallery_prop_change,
281                                                                     evas_object_evas_get(eo));
282         }
283
284         gl_dbg("_gallery_create_win:done");
285         gl_dbg_launch("  _gallery_create_win:end");
286         return eo;
287 }
288
289 /* Parent is main window */
290 static Evas_Object *_gallery_create_bg(Evas_Object *parent)
291 {
292         gl_dbg_launch("    _gallery_create_bg:start");
293         GL_CHECK_NULL(parent);
294         Evas_Object *bg = NULL;
295
296         gl_dbg_launch("      elm_bg_add:start");
297         bg = elm_bg_add(parent);
298         gl_dbg_launch("      elm_bg_add:end");
299         /* Show special color of background */
300         elm_bg_color_set(bg, GL_BG_COLOR_R, GL_BG_COLOR_G, GL_BG_COLOR_B);
301         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND,
302                                          EVAS_HINT_EXPAND);
303         evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
304         elm_win_resize_object_add(parent, bg);
305         evas_object_show(bg);
306         gl_dbg_launch("    _gallery_create_bg:end");
307
308         return bg;
309 }
310
311 /* Parent is main window */
312 static Evas_Object *_gallery_create_conform(Evas_Object *parent)
313 {
314         gl_dbg_launch("    _gallery_create_conform:start");
315         GL_CHECK_NULL(parent);
316         Evas_Object *conform = NULL;
317
318         gl_dbg_launch("      elm_conformant_add:start");
319         conform = elm_conformant_add(parent);
320         gl_dbg_launch("      elm_conformant_add:end");
321
322         evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND,
323                                          EVAS_HINT_EXPAND);
324         evas_object_size_hint_align_set(conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
325         elm_win_resize_object_add(parent, conform);
326         evas_object_show(conform);
327         gl_dbg_launch("    _gallery_create_conform:end");
328
329         return conform;
330 }
331
332 static int _gallery_create_view_ly(gl_appdata *ad)
333 {
334         gl_dbg_launch("    _gallery_create_view_ly:start");
335         GL_CHECK_VAL(ad, -1);
336         GL_CHECK_VAL(ad->maininfo.naviframe, -1);
337         Evas_Object *cbar = NULL;
338
339         Evas_Object *layout = gl_ctrl_create_ctrlbar_view(ad->maininfo.naviframe);
340
341         ad->ctrlinfo.ctrlbar_view_ly = layout;
342
343         /* create controlbar downside */
344         cbar = gl_ctrl_create_ctrlbar(ad, GL_CTRL_TAB_ALBUMS);
345         elm_object_part_content_set(ad->ctrlinfo.ctrlbar_ly,
346                                     "elm.swallow.tabbar", cbar);
347         _gl_ctrl_show_tabbar(ad, true);
348         ad->ctrlinfo.ctrlbar = cbar;
349
350         gl_ui_create_title_and_push(ad, ad->maininfo.naviframe,
351                                     ad->ctrlinfo.ctrlbar_view_ly,
352                                     GL_NAVI_ALBUMS, GL_STR_CTRL_ITEM_ALBUMS);
353         gl_dbg_launch("    _gallery_create_view_ly:end");
354
355         return 0;
356 }
357
358 static Eina_Bool __gallery_activate_win_idler_cb(void *data)
359 {
360         GL_CHECK_CANCEL(data);
361         gl_appdata *ad = (gl_appdata *)data;
362
363         gl_dbgW("elm_win_activate - start!");
364         elm_win_activate(ad->maininfo.win);
365         gl_dbgW("elm_win_activate - done!");
366
367         if (ad->albuminfo.activate_win_idler) {
368                 ecore_idler_del(ad->albuminfo.activate_win_idler);
369                 ad->albuminfo.activate_win_idler = NULL;
370         }
371
372         return ECORE_CALLBACK_CANCEL;
373 }
374
375 static Eina_Bool _gallery_create_albums_idler_cb(void *data)
376 {
377         gl_dbg_launch("  _gallery_create_albums_idler_cb:start");
378         GL_CHECK_CANCEL(data);
379         gl_appdata *ad = (gl_appdata *)data;
380         gl_dbg("_gallery_create_albums_idler_cb:start");
381
382         gl_dbgW("\tIdler: gallery is launched!");
383
384         /* Initialize libmedia-info */
385         _gl_data_init();
386         gl_dbg("DB initialization:done");
387         /* Get cluster list from libmedia-info */
388         gl_dbg_launch("    _gl_data_get_cluster_list:start");
389         _gl_data_get_cluster_list(ad);
390         gl_dbg_launch("    _gl_data_get_cluster_list:end");
391         GL_CHECK_FALSE(ad->albuminfo.cluster_list);
392         gl_dbg("_gl_data_get_cluster_list:done");
393         /* Set view mode */
394         gl_set_view_mode(ad, GL_VIEW_ALBUMS);
395         /**
396         * Disbale 'edit' button if none editable albums
397         * (albums except 'All albums'/'Camera shot'/'AllShare') exist.
398         */
399         if (gl_check_gallery_empty(ad) ||
400             ad->albuminfo.cluster_list->edit_cnt == 0)
401                 _gl_ctrl_disable_btn(ad, true, GL_NAVI_ALBUMS);
402         /* Update albums view, append items  */
403         gl_albums_update_items(ad);
404
405         /**
406         * Disable control bar when none album exists.
407         * or File system is unmounted.
408         */
409         if (gl_check_gallery_empty(ad))
410                 gl_ctrl_disable_ctrlbar(ad, true);
411         else
412                 gl_ctrl_disable_ctrlbar(ad, false);
413
414         gl_dbg("_gallery_create_albums_idler_cb:done");
415
416         if (ad->albuminfo.create_albums_idler) {
417                 ecore_idler_del(ad->albuminfo.create_albums_idler);
418                 ad->albuminfo.create_albums_idler = NULL;
419         }
420
421         gl_dbg_launch("  _gallery_create_albums_idler_cb:end");
422         return ECORE_CALLBACK_CANCEL;
423 }
424
425 /**
426  * <layout>
427  * Elm_win
428  *    |-> Elm_bg
429  *    |-> Elm_conformant
430  *        |-> Elm_layout(main_layout)
431  *            |-> Elm_layout(ctrlbar_ly)
432  *                |-> Elm_naviframe(naviframe)
433  *                     |-> Elm_layout(ctrlbar_view_ly)
434  *                          |-> Elm_gengrid(albums_view/tags_view/places_view/...)
435 */
436 static int _gallery_init_view(gl_appdata *ad)
437 {
438         gl_dbg_launch("  _gallery_init_view:start");
439         gl_dbg("");
440         GL_CHECK_VAL(ad, -1);
441         Evas_Object *ly = NULL;
442
443         /* Background. */
444         ad->maininfo.bg = _gallery_create_bg(ad->maininfo.win);
445         GL_CHECK_VAL(ad->maininfo.bg, -1);
446         /* Conformant. */
447         Evas_Object *conform = _gallery_create_conform(ad->maininfo.win);
448         GL_CHECK_VAL(conform, -1);
449         /* Set if this window is an illume conformant window */
450         elm_win_conformant_set(ad->maininfo.win, EINA_TRUE);
451         /* Base Layout */
452         ad->maininfo.main_layout = gl_ui_create_main_ly(conform);
453         GL_CHECK_VAL(ad->maininfo.main_layout, -1);
454         /* Set base layout to conformant */
455         elm_object_content_set(conform, ad->maininfo.main_layout);
456         /* Indicator */
457         elm_win_indicator_mode_set(ad->maininfo.win, ELM_WIN_INDICATOR_SHOW);
458         gl_dbg("gl_ui_create_main_ly: done");
459         /* Create control layout */
460         ly = gl_ctrl_create_ctrlbar_ly(ad->maininfo.main_layout);
461         GL_CHECK_VAL(ly, -1);
462         ad->ctrlinfo.ctrlbar_ly = ly;
463         /* Set control layout to main layout */
464         elm_object_part_content_set(ad->maininfo.main_layout,
465                                     "elm.swallow.content", ly);
466         /* Create Naviframe */
467         ad->maininfo.naviframe = gl_ui_create_naviframe(ad->ctrlinfo.ctrlbar_ly);
468         GL_CHECK_VAL(ad->maininfo.naviframe, -1);
469         /* Set Naviframe to control layout */
470         elm_object_part_content_set(ad->ctrlinfo.ctrlbar_ly,
471                                     "elm.swallow.content",
472                                     ad->maininfo.naviframe);
473
474         evas_object_data_set(ad->maininfo.naviframe, GL_NAVIFRAME_OBJ_DATA_KEY,
475                              conform);
476
477         gl_dbg("gl_ctrl_create_ctrlbar_view: done");
478
479         /* Create view layout and Set view layout to Naviframe*/
480         _gallery_create_view_ly(ad);
481
482         /* Add albums view and append nothing */
483         Evas_Object *layout_inner = NULL;
484         layout_inner = _gl_albums_add_gengrid(ad, ad->ctrlinfo.ctrlbar_view_ly);
485         GL_CHECK_FALSE(layout_inner);
486         elm_object_part_content_set(ad->ctrlinfo.ctrlbar_view_ly, "contents",
487                                     layout_inner);
488         ad->albuminfo.albums_view = layout_inner;
489         ad->albuminfo.gallery_launched = true;
490
491         gl_dbg_launch("  _gallery_init_view:end");
492
493         return 0;
494 }
495
496 static bool _gallery_create(void *data)
497 {
498         gl_dbg_launch("create:start");
499         gl_dbgW("==Create==");
500         GL_CHECK_FALSE(data);
501         gl_appdata *ad = (gl_appdata *)data;
502         ad->maininfo.reentrant = TRUE;
503         Evas_Object *win = NULL;
504
505         elm_theme_extension_add(NULL, GL_EDJ_FILE);
506
507         /* create window */
508         win = _gallery_create_win(ad, PACKAGE);
509         GL_CHECK_FALSE(win);
510         ad->maininfo.win = win;
511
512         /* initialize gallery view */
513         if (_gallery_init_view(ad) != 0) {
514                 gl_dbgE("_gallery_init_view failed");
515                 return false;
516         }
517         /* _gallery_lang_changed_cb(ad); */
518
519         gl_dbg_launch("  evas_object_show(win):start");
520         evas_object_show(win);
521         gl_dbg_launch("  evas_object_show(win):end");
522         gl_dbg("evas_object_show(win):done");
523         /* Register callbacks of DB update */
524         gl_dbg("system event cb:done");
525
526         gl_dbg_launch("  register callbacks:start");
527         gl_reg_db_update_noti(ad);
528         /* Register key down handler */
529         ad->maininfo.keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
530                                                                __gallery_key_down_cb,
531                                                                data);
532         gl_dbg_launch("  register callbacks:end");
533
534         if (ad->albuminfo.create_albums_idler == NULL) {
535                 /* Use idler to load albums view */
536                 Ecore_Idler *idl = NULL;
537                 idl = ecore_idler_add(_gallery_create_albums_idler_cb, ad);
538                 ad->albuminfo.create_albums_idler = idl;
539                 gl_dbg("create_albums_idler added: 0x%x",
540                        ad->albuminfo.create_albums_idler);
541         }
542         gl_dbg_launch("create:end");
543
544         return true;
545 }
546
547 static int _gallery_close_app(void *data)
548 {
549         GL_CHECK_VAL(data, -1);
550         gl_appdata *ad = (gl_appdata *)data;
551
552         if (ad->albuminfo.create_albums_idler) {
553                 ecore_idler_del(ad->albuminfo.create_albums_idler);
554                 ad->albuminfo.create_albums_idler = NULL;
555         }
556
557         if (ad->albuminfo.activate_win_idler) {
558                 ecore_idler_del(ad->albuminfo.activate_win_idler);
559                 ad->albuminfo.activate_win_idler = NULL;
560         }
561         /* Destroy idler */
562         _gl_thumbs_del_append_idler(ad);
563         /* destroy rename album job.*/
564         if(ad->maininfo.rename_album_job) {
565                 ecore_job_del(ad->maininfo.rename_album_job);
566                 ad->maininfo.rename_album_job = NULL;
567         }
568         /* Destroy vibration timer */
569         if (ad->entryinfo.vibration_timer) {
570                 ecore_timer_del(ad->entryinfo.vibration_timer);
571                 ad->entryinfo.vibration_timer = NULL;
572         }
573         /* Free Ecore_Pipe object created */
574         if (ad->pbarinfo.sync_pipe) {
575                 ecore_pipe_del(ad->pbarinfo.sync_pipe);
576                 ad->pbarinfo.sync_pipe = NULL;
577         }
578
579         if (ad->pbarinfo.start_thread_timer) {
580                 ecore_timer_del(ad->pbarinfo.start_thread_timer);
581                 ad->pbarinfo.start_thread_timer = NULL;
582         }
583
584         if (ad->pbarinfo.del_pbar_idler) {
585                 ecore_idler_del(ad->pbarinfo.del_pbar_idler);
586                 ad->pbarinfo.del_pbar_idler = NULL;
587         }
588
589         /* Destroy timer for removing popup */
590         if (ad->popupinfo.del_timer) {
591                 ecore_timer_del(ad->popupinfo.del_timer);
592                 ad->popupinfo.del_timer = NULL;
593         }
594
595         /* Remove down event handler */
596         if(ad->maininfo.keydown_handler) {
597                 ecore_event_handler_del(ad->maininfo.keydown_handler);
598                 ad->maininfo.keydown_handler = NULL;
599         }
600
601         /*Remove font type change event handler*/
602         if (ad->maininfo.font_handler) {
603                 ecore_event_handler_del(ad->maininfo.font_handler);
604                 ad->maininfo.font_handler = NULL;
605         }
606
607         /* Remove key data for confirmant */
608         evas_object_data_del(ad->maininfo.naviframe, GL_NAVIFRAME_OBJ_DATA_KEY);
609         /* Remove IMF */
610         _gl_editfield_destroy_imf(ad);
611
612         _gl_ctxpopup_del(ad);
613
614         /* Clear data about thumb callbacks */
615         _gl_destroy_thumbs_edit_view(ad);
616         if (ad->gridinfo.select_view)
617                 _gl_thumbs_clear_cbs(ad->gridinfo.select_view);
618         _gl_thumbs_delete_view(ad);
619
620         /* DB update callback unregister. */
621         gl_dereg_db_update_noti();
622
623         /* Free memory allocated for appcontrol */
624         _gallery_init_app_svc(ad);
625
626         ug_destroy_all();
627 #if 0
628         if (ad->maininfo.main_layout)
629                 evas_object_del(ad->maininfo.main_layout);
630 #endif
631 /*BS launched after connecting to PC while Gallery open in mass storage mode.*/
632 #if 0
633         if (ad->maininfo.win)
634                 evas_object_del(ad->maininfo.win);
635 #endif
636         gl_albums_free_data(data);
637
638         /* disconnet with libmedia-info */
639         _gl_data_finalize(ad);
640
641 #ifdef _USE_SBESM
642         _gl_ext_deinitialize_sbeam(data);
643 #endif
644
645         gl_dbgW("==Cleaning done==");
646
647         return 0;
648 }
649
650 static void _gallery_terminate(void *data)
651 {
652         gl_dbgW("==Terminate==");
653         GL_CHECK(data);
654         _gallery_close_app(data);
655 }
656
657 static void _gallery_pause(void *data)
658 {
659         gl_dbgW("==Pause==");
660         GL_CHECK(data);
661         gl_appdata *ad = (gl_appdata *)data;
662         ad->maininfo.reentrant = TRUE;
663
664         if (ad->maininfo.home_key) {
665                 gl_ext_destroy_gallery_ug(ad);
666                 ad->maininfo.home_key = false;
667         }
668
669         ug_pause();
670 }
671
672 static void _gallery_resume(void *data)
673 {
674         gl_dbg_launch("resume:start");
675         gl_dbgW("==Resume==");
676         GL_CHECK(data);
677         gl_appdata *ad = (gl_appdata *)data;
678
679         ug_resume();
680         /* Video palyer was close when pause Gallery */
681         ad->uginfo.app_called_by_me = false;
682
683         /* Show cursor and IMF if not popup showed */
684         if (ad->entryinfo.editfield) {
685                 if (ad->popupinfo.popup) {
686                         gl_dbg("Hide Entry cursor and IMF");
687                         _gl_editfield_hide_imf(ad);
688                 } else {
689                         gl_dbg("Show Entry cursor and IMF");
690                         _gl_editfield_show_imf(ad);
691                 }
692         }
693
694         /* Update view */
695         gl_update_view(ad, GL_UPDATE_VIEW_NORMAL);
696
697         gl_dbg_launch("resume:done");
698 }
699 static int __gallery_reset_app(void *data, const char *cluster_id,
700                                const char *aul_type)
701 {
702         GL_CHECK_VAL(data, -1);
703         gl_appdata *ad = (gl_appdata *)data;
704         GL_CHECK_VAL(ad->maininfo.win, -1);
705         int view_mode = gl_get_view_mode(ad);
706         gl_dbg("");
707
708         if (cluster_id == NULL || aul_type == NULL) {
709                 gl_dbgE("Invalid aul parameters!");
710                 goto GALLERY_RESET_FAILED;
711         }
712
713         if (ad->pbarinfo.sync_pipe) {
714                 gl_dbgW("Cancel move/delete pthread/Pipe!");
715                 /* Set cancel state to make child thread exit */
716                 gl_thread_set_cancel_state(ad, GL_PB_CANCEL_RESET);
717                 return -1;
718         }
719
720         if (view_mode == GL_VIEW_NONE) {
721                 /* First launch gallery then show shortcut album/tag */
722                 _gl_data_init();
723                 gl_dbg("Launch gallery at the first time");
724                 _gl_data_get_cluster_list(ad);
725                 GL_CHECK_VAL(ad->albuminfo.cluster_list, -1);
726                 /* Set view mode */
727                 gl_set_view_mode(ad, GL_VIEW_ALBUMS);
728                 /* Select tabbar item contains shortcut item */
729                 _gl_ctrl_sel_tabbar_item(ad, aul_type);
730         } else if (ad->ctrlinfo.tab_mode == GL_CTRL_TAB_TAGS) {
731                 gl_dbg("In Tags tab");
732                 if (_gl_tags_reset_view(ad, cluster_id, aul_type) < 0)
733                         goto GALLERY_RESET_FAILED;
734         } else {
735                 gl_dbg("In Albums tab");
736                 if (_gl_albums_reset_view(ad, cluster_id, aul_type) < 0)
737                         goto GALLERY_RESET_FAILED;
738         }
739
740         if (g_strcmp0(cluster_id, GL_ALBUM_ALL_ID) == 0 &&
741             g_strcmp0(aul_type, GL_AUL_ALBUM) == 0)
742                 goto GALLERY_RESET_SUCCESS;
743
744         /* Remove idler for other tabbar item */
745         if (ad->albuminfo.create_albums_idler) {
746                 gl_dbgW("Remove album creation idler!");
747                 ecore_idler_del(ad->albuminfo.create_albums_idler);
748                 ad->albuminfo.create_albums_idler = NULL;
749         }
750
751         if (!g_strcmp0(aul_type, GL_AUL_TAG)) {
752                 /* Show shortcut tag */
753                 if (_gl_tags_sel_home_tag(ad, cluster_id) == false) {
754                         /* Tag doesn't exist */
755                         gl_dbgE("Tag(livepanel) doesn't exist!");
756                         goto GALLERY_RESET_FAILED;
757                 }
758         } else {
759                 gl_dbgE("Wrong type!");
760                 goto GALLERY_RESET_FAILED;
761         }
762  GALLERY_RESET_SUCCESS:
763         elm_win_activate(ad->maininfo.win);
764         return 0;
765
766  GALLERY_RESET_FAILED:
767         elm_win_activate(ad->maininfo.win);
768         return -1;
769 }
770
771 /* init appcontrol launch related global variables */
772 static int _gallery_init_app_svc(void *data)
773 {
774         GL_CHECK_VAL(data, -1);
775         gl_dbg("");
776         gl_appdata *ad = (gl_appdata *)data;
777
778         ad->albuminfo.aul_launch_type = GL_AUL_T_NONE;
779         ad->albuminfo.aul_file_type = GL_AUL_FILE_T_NONE;
780         ad->albuminfo.aul_setas_type = GL_AUL_SETAS_T_NONE;
781         GL_FREEIF(ad->albuminfo.aul_id);
782         GL_FREEIF(ad->albuminfo.aul_type);
783         ad->albuminfo.aul_launch_by_mime = false;
784
785         if(ad->albuminfo.recv_service) {
786                 service_destroy(ad->albuminfo.recv_service);
787                 ad->albuminfo.recv_service = NULL;
788         }
789
790         GL_FREEIF(ad->albuminfo.aul_callid_size);
791         GL_FREEIF(ad->albuminfo.aul_callid_path);
792         GL_FREEIF(ad->albuminfo.aul_homescreen_path);
793         GL_FREEIF(ad->albuminfo.aul_lockscreen_path);
794         return 0;
795 }
796
797 static int __gallery_parse_contain_drm(void *data, service_h service)
798 {
799         GL_CHECK_VAL(service, -1);
800         GL_CHECK_VAL(data, -1);
801         gl_appdata *ad = (gl_appdata *)data;
802         char *contain_drm = NULL;
803
804         ad->albuminfo.b_show_drm = false;
805         service_get_extra_data(service, GL_BD_DRM_TYPE, &contain_drm);
806         gl_dbg("DRM: %s", contain_drm);
807         if (contain_drm) {
808                 if (!strcasecmp(contain_drm, GL_BD_SHOW_DRM_FILE))
809                         ad->albuminfo.b_show_drm= true;
810                 GL_FREE(contain_drm);
811         }
812
813         return 0;
814 }
815
816 static int __gallery_parse_launch_type(void *data, service_h service)
817 {
818         GL_CHECK_VAL(service, -1);
819         GL_CHECK_VAL(data, -1);
820         gl_appdata *ad = (gl_appdata *)data;
821         gl_aul_launch_type launch_type = GL_AUL_T_NONE;
822         char *launch_type_str = NULL;
823         char *select_mode = NULL;
824         char *setas_type_str = NULL;
825         gl_dbg("");
826
827         /* get launch-type */
828         service_get_extra_data(service, GL_BD_SELECTION_MODE, &select_mode);
829         if (select_mode) {
830                 if (!strcasecmp(select_mode, GL_BD_SELECTION_MODE_SINGLE)) {
831                         ad->albuminfo.aul_launch_type = GL_AUL_T_SELECT_ONE;
832                         GL_FREEIF(select_mode);
833                         return 0;
834                 } else if (!strcasecmp(select_mode, GL_BD_SELECTION_MODE_MULTI)) {
835                         ad->albuminfo.aul_launch_type = GL_AUL_T_SELECT_MULTIPLE;
836                         GL_FREEIF(select_mode);
837                         return 0;
838                 }
839         }
840         service_get_extra_data(service, GL_BD_LAUNCH_TYPE, &launch_type_str);
841         if (launch_type_str == NULL) {
842                 gl_dbg("set to default launch type: select-one");
843                 ad->albuminfo.aul_launch_type = GL_AUL_T_SELECT_ONE;
844                 return 0;
845         } else {
846                 gl_dbg("launch-type: %s", launch_type_str);
847         }
848
849         if(!strcasecmp(launch_type_str, GL_BD_SELECT_ALBUM)) {
850                 launch_type = GL_AUL_T_SELECT_ALBUM;
851         } else  if(!strcasecmp(launch_type_str, GL_BD_SELECT_ONE)) {
852                 launch_type = GL_AUL_T_SELECT_ONE;
853         } else  if(!strcasecmp(launch_type_str, GL_BD_SELECT_MULTIPLE)) {
854                 launch_type = GL_AUL_T_SELECT_MULTIPLE;
855         } else  if(!strcasecmp(launch_type_str, GL_BD_SELECT_SETAS)) {
856                 launch_type = GL_AUL_T_SELECT_SETAS;
857
858                 /* get setas-type */
859                 service_get_extra_data(service, GL_BD_SETAS_TYPE, &setas_type_str);
860                 if(setas_type_str == NULL) {
861                         GL_FREE(launch_type_str);
862                         return 0;
863                 }
864                 gl_dbg("setas-type: %s", setas_type_str);
865
866                 gl_aul_setas_type setas_type = GL_AUL_SETAS_T_NONE;
867                 char *path = NULL;
868                 char *size = NULL;
869
870                 if (!strcasecmp(setas_type_str, GL_BD_SETAS_WALLPALER)) {
871                         setas_type = GL_AUL_SETAS_T_WALLPAPER;
872
873                         /* get homscreen-path */
874                         service_get_extra_data(service, GL_BD_HOMESCREEN_PATH,
875                                                &path);
876                         if (path) {
877                                 gl_dbg("homescreen-path: %s", path);
878                                 ad->albuminfo.aul_homescreen_path = path;
879                                 path = NULL;
880                         }
881                         /* get lockscreen-path */
882                         service_get_extra_data(service, GL_BD_LOCKSCREEN_PATH,
883                                                &path);
884                         if (path) {
885                                 gl_dbg("lockscreen-path: %s", path);
886                                 ad->albuminfo.aul_lockscreen_path = path;
887                                 path = NULL;
888                         }
889                 } else if (!strcasecmp(setas_type_str, GL_BD_SETAS_CALLERID)) {
890                         setas_type = GL_AUL_SETAS_T_CALLER_ID;
891                         /* get callerid-size */
892                         service_get_extra_data(service, GL_BD_CALLERID_SIZE,
893                                                &size);
894                         if (size) {
895                                 gl_dbg("callerid-size: %s", size);
896                                 ad->albuminfo.aul_callid_size = size;
897                         }
898                         /* get callerid-path */
899                         service_get_extra_data(service, GL_BD_CALLERID_PATH,
900                                                &path);
901                         if (path) {
902                                 gl_dbg("callerid-path: %s", path);
903                                 ad->albuminfo.aul_callid_path = path;
904                         }
905                 }
906
907                 ad->albuminfo.aul_setas_type = setas_type;
908                 GL_FREE(setas_type_str);
909         }
910
911         ad->albuminfo.aul_launch_type = launch_type;
912         GL_FREE(launch_type_str);
913         return 0;
914 }
915
916 /* analysis parameters */
917 static int __gallery_parse_param(void *data, service_h service)
918 {
919         GL_CHECK_VAL(service, -1);
920         GL_CHECK_VAL(data, -1);
921         gl_dbg("");
922         gl_appdata *ad = (gl_appdata *)data;
923         char *operation = NULL;
924         char *uri = NULL;
925         char *mime = NULL;
926
927         /* init */
928         _gallery_init_app_svc(ad);
929
930         /* save current service handle */
931         service_clone(&ad->albuminfo.recv_service, service);
932
933         service_get_operation(service, &operation);
934         gl_dbg("operation: %s", operation);
935
936         service_get_uri(service, &uri);
937         if(uri) {
938                 gl_dbg("uri: %s", uri);
939                 char *str_pre = NULL;
940                 char *str_suf = NULL;
941                 str_pre = strtok_r(uri, GL_AUL_SEP, &str_suf);
942                 gl_dbg("str_pre: %s, str_suf: %s", str_pre, str_suf);
943                 GL_CHECK_VAL(str_pre, -1);
944                 GL_CHECK_VAL(str_suf, -1);
945                 str_pre = strtok_r(str_suf, GL_AUL_SEP, &str_suf);
946                 gl_dbg("str_pre: %s, str_suf: %s", str_pre, str_suf);
947                 GL_CHECK_VAL(str_pre, -1);
948                 GL_CHECK_VAL(str_suf, -1);
949                 ad->albuminfo.aul_id = strdup(str_suf);
950                 ad->albuminfo.aul_type = strdup(str_pre);
951                 ad->albuminfo.aul_launch_by_mime = true;
952                 gl_dbg("Type: %s, ID: %s", ad->albuminfo.aul_type,
953                        ad->albuminfo.aul_id);
954                 return 0;
955         }
956
957         if(!strcasecmp(operation, SERVICE_OPERATION_DEFAULT)) {
958                 return -1;
959         } else if (!strcasecmp(operation, SERVICE_OPERATION_VIEW)) {
960                 /* OPERATION_VIEW */
961                 ad->albuminfo.aul_launch_type = GL_AUL_T_VIEW_ALBUM;
962
963                 /* get file-type from service */
964                 char *file_type_str = NULL;
965                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_ALL; /* default */
966                 service_get_extra_data(service, GL_BD_FILE_TYPE, &file_type_str);
967                 if(file_type_str) {
968                         gl_dbg("file type: %s", file_type_str);
969                         if (!g_strcmp0(file_type_str, GL_BD_FILE_TYPE_IMAGE)) {
970                                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_IMAGE;
971                         } else if (!g_strcmp0(file_type_str, GL_BD_FILE_TYPE_VIDEO)) {
972                                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_VIDEO;
973                         }
974                         GL_FREE(file_type_str);
975                 }
976                 /* get album-id */
977                 char *album_id_str = NULL;
978                 service_get_extra_data(service, GL_BD_ALBUM_ID, &album_id_str);
979
980                 if(album_id_str) {
981                         gl_dbg("album-id: %s", album_id_str);
982                         ad->albuminfo.aul_id = album_id_str;
983                 } else {
984                         gl_dbg("album-id is invalid, set to default (ALL)");
985                         ad->albuminfo.aul_id = strdup(GL_ALBUM_ALL_ID);
986                 }
987                 /* To show album, so tabbar item must be Albums */
988                 ad->albuminfo.aul_type = strdup(GL_AUL_ALBUM);
989         } else if (!strcasecmp(operation, SERVICE_OPERATION_PICK)) {
990                 /* OPERATION_PICK */
991                 /* get file-type from mime */
992                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_ALL; /* default */
993                 service_get_mime(service, &mime);
994                 if(mime) {
995
996                         gl_dbg("mime: %s", mime);
997                         if (!g_strcmp0(mime, GL_MIME_IMAGE_ALL)) {
998                                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_IMAGE;
999                         } else if (!g_strcmp0(mime, GL_MIME_VIDEO_ALL)) {
1000                                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_VIDEO;
1001                         }
1002                 }
1003
1004                 __gallery_parse_launch_type(ad, service);
1005                 __gallery_parse_contain_drm(ad, service);
1006         } else if (!strcasecmp(operation, GL_SERVICE_OPERATION_WALLPAPER)) {
1007                 /* Wallpaper */
1008                 ad->albuminfo.aul_file_type = GL_AUL_FILE_T_IMAGE;
1009                 ad->albuminfo.aul_launch_type = GL_AUL_T_SELECT_SETAS;
1010                 /* The wallpaper doesn't need crop currently, but IV ug returns "crop_image_path" */
1011                 ad->albuminfo.aul_setas_type = GL_AUL_SETAS_T_CROP_WALLPAPER;
1012                 __gallery_parse_contain_drm(ad, service);
1013
1014                 char *path = NULL;
1015                 service_get_extra_data(service, GL_BD_HOMESCREEN_PATH, &path);
1016                 if (path) {
1017                         gl_dbg("homescreen-path: %s", path);
1018                         ad->albuminfo.aul_homescreen_path = path;
1019                 }
1020         }
1021
1022         return 0;
1023 }
1024
1025 static void _gallery_reset(service_h service, void *data)
1026 {
1027         gl_dbgW("==Reset==");
1028         GL_CHECK(data);
1029         gl_appdata *ad = (gl_appdata *)data;
1030         GL_CHECK(ad->maininfo.win);
1031
1032         if (ad->maininfo.reentrant) {
1033                 ad->maininfo.reentrant = FALSE;
1034         } else {
1035                 gl_dbgW("Gallery reentrant is not allowed, return!");
1036                 return;
1037         }
1038
1039         /* Destroy gallery ug */
1040         if (ad->uginfo.gallery_ug_called_by_me) {
1041                 gl_dbgW("Destroy Gallery UG launched, show App view!");
1042                 ug_destroy(ad->uginfo.gallery_ug_called_by_me);
1043                 ad->uginfo.gallery_ug_called_by_me = NULL;
1044         }
1045
1046         /* Parse parameters */
1047         if(__gallery_parse_param(data, service) != 0) {
1048                 if (ad->albuminfo.aul_launch_by_mime == false &&
1049                     ad->albuminfo.aul_launch_type == GL_AUL_T_NONE) {
1050 /*@@ 1. Launch Gallery from menu screen/Smart search app, albums view showed @@*/
1051                         int view_m = gl_get_view_mode(ad);
1052                         gl_dbg("view_m: %d", view_m);
1053                         /* Launch Gallery at the first time */
1054                         if (view_m == GL_VIEW_NONE) {
1055                                 gl_dbg("Set view mode as GL_VIEW_ALBUMS");
1056                                 gl_set_view_mode(ad, GL_VIEW_ALBUMS);
1057                         } else {
1058                                 gl_dbg("Update view");
1059                                 gl_update_view(ad, GL_UPDATE_VIEW_NORMAL);
1060                         }
1061                 } else {
1062                         gl_dbgE("Failed to parse parameters, update view!");
1063                         gl_update_view(ad, GL_UPDATE_VIEW_NORMAL);
1064                 }
1065                 elm_win_activate(ad->maininfo.win);
1066                 return;
1067         }
1068
1069         if (ad->albuminfo.aul_launch_by_mime ||
1070             ad->albuminfo.aul_launch_type == GL_AUL_T_VIEW_ALBUM) {
1071 /*@@ 2. Launch Gallery from live-magazine/shortcut(add to home) @@*/
1072                 __gallery_reset_app(data, ad->albuminfo.aul_id,
1073                                     ad->albuminfo.aul_type);
1074         } else {
1075 /*@@ 3. Load Gallery UG @@*/
1076                 gl_dbg("Start loading Gallery UG");
1077                 if (gl_ext_load_gallery_ug(ad) == GL_UG_SUCCESS) {
1078                         if (gl_get_view_mode(ad) == GL_VIEW_NONE) {
1079                                 gl_dbg("elm_win_activate");
1080                                 elm_win_activate(ad->maininfo.win);
1081                         } else {
1082                                 if (ad->albuminfo.activate_win_idler) {
1083                                         ecore_idler_del(ad->albuminfo.activate_win_idler);
1084                                         ad->albuminfo.activate_win_idler = NULL;
1085                                 }
1086                                 /* To show UG faster then app */
1087                                 Ecore_Idler *idler = NULL;
1088                                 idler = ecore_idler_add(__gallery_activate_win_idler_cb,
1089                                                         ad);
1090                                 ad->albuminfo.activate_win_idler = idler;
1091                         }
1092                 }
1093         }
1094 }
1095
1096 int gallery_reset_app(void *data)
1097 {
1098         GL_CHECK_VAL(data, -1);
1099         gl_appdata *ad = (gl_appdata *)data;
1100         gl_dbg("Reset gallery[cluster ID: %s]", ad->albuminfo.aul_id);
1101         return __gallery_reset_app(data, ad->albuminfo.aul_id,
1102                                    ad->albuminfo.aul_type);
1103 }
1104
1105 int main(int argc, char *argv[])
1106 {
1107         gl_dbg_launch("main:start");
1108         gl_dbgW("==Gallery==");
1109         gl_appdata gl_ad;
1110         int ret;
1111
1112         app_event_callback_s event_callback;
1113
1114         event_callback.create = _gallery_create;
1115         event_callback.terminate = _gallery_terminate;
1116         event_callback.pause = _gallery_pause;
1117         event_callback.resume = _gallery_resume;
1118         event_callback.service = _gallery_reset;
1119         event_callback.low_memory = NULL;
1120         event_callback.low_battery = _gallery_low_battery_cb;
1121         event_callback.device_orientation = NULL;
1122         event_callback.language_changed = _gallery_lang_changed_cb;
1123         event_callback.region_format_changed = NULL;
1124
1125         /* Enable OpenGL */
1126         setenv("ELM_ENGINE", "gl", 1);
1127
1128         memset(&gl_ad, 0x00, sizeof(gl_appdata));
1129
1130         ret = app_efl_main(&argc, &argv, &event_callback, &gl_ad);
1131
1132         gl_dbgW("==Gallery gone==");
1133         gl_dbg_launch("main:done");
1134         return ret;
1135 }