tizen 2.4 release
[apps/home/attach-panel.git] / src / attach_panel.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 <app_control.h>
18 #include <bundle.h>
19 #include <Elementary.h>
20 #include <ui-gadget-module.h>
21 #include <isf_control.h>
22 #include <system_info.h>
23 #include <tizen.h>
24 #include <privilege_checker.h>
25 #include <ui-gadget.h>
26
27 #include "attach_panel.h"
28 #include "attach_panel_internal.h"
29 #include "attach_bundle.h"
30 #include "conf.h"
31 #include "content_list.h"
32 #include "gesture.h"
33 #include "grid.h"
34 #include "ui_manager.h"
35 #include "list.h"
36 #include "log.h"
37 #include "scroller.h"
38 #include "toolbar.h"
39
40 static const char *const ATTACH_PANEL_DOMAIN = "attach-panel";
41 static const char *const PLATFORM_FEATURE_CAMERA = "tizen.org/feature/camera";
42 static const char *const PLATFORM_FEATURE_MICROPHONE = "tizen.org/feature/microphone";
43
44
45
46 innate_content_s innate_content_info[ATTACH_PANEL_CONTENT_CATEGORY_VIDEO_RECORDER] = {
47         {
48                 .appid = "attach-panel-gallery",
49                 .name = "IDS_COM_TAB4_IMAGES_ABB2",
50                 .operation = APP_CONTROL_OPERATION_PICK,
51                 .selection_mode = "single",
52                 .tabbar_name = "IDS_COM_TAB4_IMAGES_ABB2",
53                 .mime = "image/*",
54                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_IMAGE,
55                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_UG,
56         },
57         {
58                 .appid = "attach-panel-camera",
59                 .name = "IDS_COM_TAB4_CAMERA",
60                 .operation = APP_CONTROL_OPERATION_CREATE_CONTENT,
61                 .selection_mode = "single",
62                 .tabbar_name = "IDS_COM_TAB4_CAMERA",
63                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_CAMERA,
64                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_UG,
65         },
66         {
67                 .appid = "attach-panel-voicerecorder",
68                 .name = "IDS_COM_TAB4_VOICE",
69                 .operation = APP_CONTROL_OPERATION_CREATE_CONTENT,
70                 .selection_mode = "single",
71                 .tabbar_name = "IDS_COM_TAB4_VOICE",
72                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_VOICE,
73                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_UG,
74         },
75         {
76                 .appid = "videos",
77                 .name = "IDS_COM_BUTTON2_VIDEOS",
78                 .operation = APP_CONTROL_OPERATION_PICK,
79                 .icon = "/usr/share/icons/video.png",
80                 .selection_mode = "multiple",
81                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
82                 .mime = "video/*",
83                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_VIDEO,
84                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
85         },
86         {
87                 .appid = "audio",
88                 .name = "IDS_COM_BUTTON2_AUDIO_FILES",
89                 .operation = APP_CONTROL_OPERATION_PICK,
90                 .icon = "/usr/share/icons/music.png",
91                 .selection_mode = "multiple",
92                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
93                 .mime = "audio/*",
94                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_AUDIO,
95                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
96         },
97         {
98                 .appid = "calendar",
99                 .name = "IDS_EMAIL_BUTTON2_CALENDAR",
100                 .operation = APP_CONTROL_OPERATION_PICK,
101                 .icon = "/usr/share/icons/calendar.png",
102                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
103                 .mode = 1,
104                 .type = "vcs",
105                 .selection_mode = "multiple",
106                 .mime = "application/vnd.tizen.calendar",
107                 .max = 1,
108                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_CALENDAR,
109                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
110         },
111         {
112                 .appid = "contacts",
113                 .name = "IDS_COM_BUTTON2_CONTACTS",
114                 .operation = APP_CONTROL_OPERATION_PICK,
115                 .icon = "/usr/share/icons/contact.png",
116                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
117                 .type = "vcf",
118                 .item_type = "person",
119                 .selection_mode = "multiple",
120                 .mime = "application/vnd.tizen.contact",
121                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_CONTACT,
122                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
123         },
124         {
125                 .appid = "myfiles",
126                 .name = "IDS_COM_BUTTON_MY_FILES_ABB",
127                 .operation = APP_CONTROL_OPERATION_PICK,
128                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
129                 .icon = "/usr/share/icons/my_files.png",
130                 .selection_mode = "multiple",
131                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_MYFILES,
132                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
133         },
134         {
135                 .appid = "record_video",
136                 .name = "IDS_IDLE_BUTTON2_RECORD_NVIDEO_ABB",
137                 .operation = APP_CONTROL_OPERATION_CREATE_CONTENT,
138                 .icon = "/usr/share/icons/default.png",
139                 .tabbar_name = "IDS_COM_TAB4_MORE_ABB",
140                 .selection_mode = "single",
141                 .mime = "video/3gp",
142                 .content_category = ATTACH_PANEL_CONTENT_CATEGORY_VIDEO_RECORDER,
143                 .is_ug = ATTACH_PANEL_CONTENT_CATEGORY_APP,
144         },
145 };
146
147
148
149 static Evas_Object *__attach_panel_rect_add(Evas_Object *conformant, int height)
150 {
151         Evas_Object *rect = NULL;
152
153         retv_if(!conformant, NULL);
154
155         _D("attach panel rect create, height : %d", height);
156
157         rect = evas_object_rectangle_add(evas_object_evas_get(conformant));
158         retv_if(!rect, NULL);
159
160         evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
161         evas_object_size_hint_align_set(rect, EVAS_HINT_FILL, 1.0);
162         evas_object_size_hint_min_set(rect, 0, height);
163         evas_object_color_set(rect, 0, 0, 0, 0);
164         evas_object_show(rect);
165
166         return rect;
167 }
168
169
170
171 static void __attach_panel_rect_del(Evas_Object *rect)
172 {
173         ret_if(!rect);
174         evas_object_del(rect);
175 }
176
177
178
179 static void __rotate_cb(void *data, Evas_Object *obj, void *event)
180 {
181         Evas_Object *win = obj;
182         attach_panel_h attach_panel = data;
183
184         int w, h;
185         int angle = 0;
186
187         ret_if(!attach_panel);
188         ret_if(!attach_panel->conformant);
189
190         angle = elm_win_rotation_get(win);
191         elm_win_screen_size_get(win, NULL, NULL, &w, &h);
192         _D("Angle is %d degree, win size is %d, %d", angle, w, h);
193
194         switch(angle) {
195         case 90:
196         case 270:
197                 _D("resize the attach-panel to land(%d)", angle);
198                 if (90 == angle)
199                         ug_send_event(UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN);
200                 else
201                         ug_send_event(UG_EVENT_ROTATE_LANDSCAPE);
202
203                 w = h;
204                 attach_panel->rotate = EINA_TRUE;
205
206                 if (ATTACH_PANEL_STATE_HIDE == attach_panel->attach_panel_port_state) {
207                         attach_panel->attach_panel_land_state = ATTACH_PANEL_STATE_HIDE;
208                 } else if (ATTACH_PANEL_STATE_HALF == attach_panel->attach_panel_port_state) {
209                         attach_panel->attach_panel_land_state = ATTACH_PANEL_STATE_FULL;
210                         _gesture_set_state(ATTACH_PANEL_STATE_FULL);
211                         _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_MULTIPLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
212                         elm_object_signal_emit(attach_panel->conformant, "elm,state,attach_panel,show,full", "");
213                 } else {
214                         attach_panel->attach_panel_land_state = ATTACH_PANEL_STATE_FULL;
215                         _gesture_set_state(ATTACH_PANEL_STATE_FULL);
216                 }
217                 break;
218         case 0:
219         case 180:
220                 _D("resize the attach-panel to port(%d)", angle);
221                 if (0 == angle)
222                         ug_send_event(UG_EVENT_ROTATE_PORTRAIT);
223                 else
224                         ug_send_event(UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN);
225
226                 attach_panel->rotate = EINA_FALSE;
227
228                 if (ATTACH_PANEL_STATE_HIDE == attach_panel->attach_panel_land_state) {
229                         attach_panel->attach_panel_port_state = ATTACH_PANEL_STATE_HIDE;
230                 } else {
231                         if (ATTACH_PANEL_STATE_HALF == attach_panel->attach_panel_port_state) {
232                                 _gesture_set_state(ATTACH_PANEL_STATE_HALF);
233                                 _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_SINGLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
234                                 elm_object_signal_emit(attach_panel->conformant, "elm,state,attach_panel,show,half", "");
235                         } else {
236                                 attach_panel->attach_panel_port_state = ATTACH_PANEL_STATE_FULL;
237                                 _gesture_set_state(ATTACH_PANEL_STATE_FULL);
238                         }
239                 }
240                 break;
241         default:
242                 _E("cannot reach here");
243                 break;
244         }
245
246         _scroller_resize(attach_panel->scroller, w, 0);
247         elm_scroller_page_show(attach_panel->scroller, attach_panel->cur_page_no, 0);
248 }
249
250
251
252 EXPORT_API int attach_panel_create(Evas_Object *conformant, attach_panel_h *attach_panel)
253 {
254         Evas_Object *old_panel = NULL;
255         attach_panel_h panel = NULL;
256         const char *type = NULL;
257         int width = 0;
258         int height = 0;
259         int base_height = 0;
260
261         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
262         retv_if(!conformant, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
263
264         old_panel = elm_object_part_content_get(conformant, "elm.swallow.attach_panel");
265         retv_if(old_panel, ATTACH_PANEL_ERROR_ALREADY_EXISTS);
266
267         type = elm_object_widget_type_get(conformant);
268         retv_if(!type, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
269
270         if (strcmp(type, "Elm_Conformant")) {
271                 _E("This is not a conformant, %s", type);
272                 return ATTACH_PANEL_ERROR_INVALID_PARAMETER;
273         }
274
275         bindtextdomain(ATTACH_PANEL_DOMAIN, "/usr/ug/res/locale");
276
277         panel = calloc(1, sizeof(attach_panel_s));
278         retv_if(!panel, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
279         panel->conformant = conformant;
280
281         evas_object_geometry_get(conformant, NULL, NULL, &width, &base_height);
282         panel->transit_width = width;
283
284         if (width > base_height) {
285                 base_height = width * BASE_TRANSIT_HEIGHT_REL;
286         } else {
287                 base_height = base_height * BASE_TRANSIT_HEIGHT_REL;
288         }
289
290         isf_control_get_recent_ime_geometry(NULL, NULL, NULL, &height);
291         if (!height || height < base_height) {
292                 _E("Fail to get the recent ime height");
293                 height = base_height;
294         }
295         panel->transit_height = height;
296
297         panel->attach_panel_rect = __attach_panel_rect_add(conformant, height);
298         goto_if(!panel->attach_panel_rect, ERROR);
299         elm_object_part_content_set(conformant, "elm.swallow.attach_panel_base", panel->attach_panel_rect);
300
301         panel->ui_manager = _ui_manager_create(panel);
302         goto_if(!panel->ui_manager, ERROR);
303         elm_object_part_content_set(conformant, "elm.swallow.attach_panel", panel->ui_manager);
304         panel->is_delete = EINA_FALSE;
305         panel->rotate = EINA_FALSE;
306         panel->flick = EINA_TRUE;
307         panel->cur_page_no = 0;
308         panel->magic_no = 0x1024;
309
310         panel->gesture = _gesture_create(panel);
311         goto_if(!panel->gesture, ERROR);
312
313         evas_object_smart_callback_add(panel->win, "wm,rotation,changed", __rotate_cb, panel);
314         elm_scroller_movement_block_set(panel->scroller, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
315         __rotate_cb(panel, panel->win, NULL);
316         *attach_panel = panel;
317
318         return ATTACH_PANEL_ERROR_NONE;
319
320 ERROR:
321         if (panel->ui_manager) {
322                 elm_object_part_content_unset(conformant, "elm.swallow.attach_panel");
323                 _ui_manager_destroy(panel->ui_manager);
324         }
325
326         if (panel->attach_panel_rect) {
327                 elm_object_part_content_unset(conformant, "elm.swallow.attach_panel_base");
328                 __attach_panel_rect_del(panel->attach_panel_rect);
329         }
330         free(panel);
331
332         return ATTACH_PANEL_ERROR_NOT_INITIALIZED;
333 }
334
335
336
337 extern void _attach_panel_del(attach_panel_h attach_panel)
338 {
339         content_s *content_info = NULL;
340         Eina_List *l = NULL;
341
342         ret_if(!attach_panel);
343         _D("%s : attach panel is destroyed", __func__);
344
345         if (0x1024 != attach_panel->magic_no) {
346                 _D("attach panel is already destroyed");
347                 return;
348         }
349
350         attach_panel->magic_no = 0;
351
352         _gesture_destroy(attach_panel);
353
354         evas_object_smart_callback_del(attach_panel->win, "wm,rotation,changed", __rotate_cb);
355         elm_object_part_content_unset(attach_panel->conformant, "elm.swallow.attach_panel_base");
356         __attach_panel_rect_del(attach_panel->attach_panel_rect);
357
358         EINA_LIST_FOREACH(attach_panel->content_list, l, content_info) {
359                 if (content_info->extra_data) {
360                         bundle_free(content_info->extra_data);
361                         content_info->extra_data = NULL;
362                 }
363         }
364
365         elm_object_part_content_unset(attach_panel->conformant, "elm.swallow.attach_panel");
366         _ui_manager_destroy(attach_panel->ui_manager);
367
368         free(attach_panel);
369 }
370
371
372
373 EXPORT_API int attach_panel_destroy(attach_panel_h attach_panel)
374 {
375         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
376         _D("%s : attach panel will be destroyed", __func__);
377
378         if (EINA_TRUE == attach_panel->is_delete) {
379                 _E("Attach panel is already removed");
380                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
381         }
382
383         attach_panel->is_delete = EINA_TRUE;
384         if (ATTACH_PANEL_STATE_HIDE == _gesture_get_state()) {
385                 _attach_panel_del(attach_panel);
386         } else {
387                 attach_panel_hide(attach_panel);
388         }
389
390         return ATTACH_PANEL_ERROR_NONE;
391 }
392
393
394
395 static void __iter_cb(const char *key, const int type, bundle_keyval_t *kv, void *user_data)
396 {
397         int *bundle_is_op = user_data;
398
399         ret_if(!key);
400         ret_if(!bundle_is_op);
401
402         if (!strncmp("__APP_SVC_", key, 10))
403                 *bundle_is_op = 1;
404 }
405
406
407
408 static const char *const PRIVILEGE_CAMERA = "http://tizen.org/privilege/camera";
409 static const char *const PRIVILEGE_RECORDER = "http://tizen.org/privilege/recorder";
410 static const char *const PRIVILEGE_APPMANAGER_LAUNCH = "http://tizen.org/privilege/appmanager.launch";
411 EXPORT_API int attach_panel_add_content_category(attach_panel_h attach_panel, attach_panel_content_category_e content_category, bundle *extra_data)
412 {
413         content_s *content_info = NULL;
414         bundle *dup_bundle = NULL;
415         Eina_List *l = NULL;
416         int ret = SYSTEM_INFO_ERROR_NONE;
417         bool value = false;
418
419         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
420         retv_if(!attach_panel->ui_manager, ATTACH_PANEL_ERROR_NOT_INITIALIZED);
421         retv_if(content_category < ATTACH_PANEL_CONTENT_CATEGORY_IMAGE, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
422         retv_if(content_category > ATTACH_PANEL_CONTENT_CATEGORY_VIDEO_RECORDER, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
423
424         if (EINA_TRUE == attach_panel->is_delete) {
425                 _E("Attach panel is already removed");
426                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
427         }
428
429         switch (content_category) {
430         case ATTACH_PANEL_CONTENT_CATEGORY_CAMERA:
431                 ret = system_info_get_platform_bool(PLATFORM_FEATURE_CAMERA, &value);
432                 break_if(SYSTEM_INFO_ERROR_NONE != ret);
433                 retv_if(false == value, ATTACH_PANEL_ERROR_UNSUPPORTED_CONTENT_CATEGORY);
434
435                 ret = privilege_checker_check_privilege(PRIVILEGE_CAMERA);
436                 retv_if(PRIVILEGE_CHECKER_ERR_UNDECLARED_PRIVILEGE == ret, ATTACH_PANEL_ERROR_PERMISSION_DENIED);
437                 break_if(PRIVILEGE_CHECKER_ERR_NONE != ret);
438                 break;
439         case ATTACH_PANEL_CONTENT_CATEGORY_VOICE:
440                 ret = system_info_get_platform_bool(PLATFORM_FEATURE_MICROPHONE, &value);
441                 break_if(SYSTEM_INFO_ERROR_NONE != ret);
442                 retv_if(false == value, ATTACH_PANEL_ERROR_UNSUPPORTED_CONTENT_CATEGORY);
443
444                 ret = privilege_checker_check_privilege(PRIVILEGE_RECORDER);
445                 retv_if(PRIVILEGE_CHECKER_ERR_UNDECLARED_PRIVILEGE == ret, ATTACH_PANEL_ERROR_PERMISSION_DENIED);
446                 break_if(PRIVILEGE_CHECKER_ERR_NONE != ret);
447                 break;
448         case ATTACH_PANEL_CONTENT_CATEGORY_VIDEO:
449         case ATTACH_PANEL_CONTENT_CATEGORY_AUDIO:
450         case ATTACH_PANEL_CONTENT_CATEGORY_CALENDAR:
451         case ATTACH_PANEL_CONTENT_CATEGORY_CONTACT:
452         case ATTACH_PANEL_CONTENT_CATEGORY_MYFILES:
453                 ret = privilege_checker_check_privilege(PRIVILEGE_APPMANAGER_LAUNCH);
454                 retv_if(PRIVILEGE_CHECKER_ERR_UNDECLARED_PRIVILEGE == ret, ATTACH_PANEL_ERROR_PERMISSION_DENIED);
455                 break_if(PRIVILEGE_CHECKER_ERR_NONE != ret);
456                 break;
457         default:
458                 break;
459         }
460
461         EINA_LIST_FOREACH(attach_panel->content_list, l, content_info) {
462                 if (content_info->innate_content_info->content_category == content_category) {
463                         _E("The content category[%d] already exists in the panel", content_category);
464                         return ATTACH_PANEL_ERROR_ALREADY_EXISTS;
465                 }
466         }
467
468         if (extra_data) {
469                 int bundle_is_op = 0;
470
471                 bundle_foreach(extra_data, (void *) __iter_cb, &bundle_is_op);
472
473                 if (bundle_is_op) {
474                         _E("bundle key is invalid value");
475                         return ATTACH_PANEL_ERROR_INVALID_PARAMETER;
476                 }
477
478                 dup_bundle = bundle_dup(extra_data);
479                 retv_if(!dup_bundle, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
480         }
481
482         _ui_manager_append_content_category(attach_panel->ui_manager, &innate_content_info[content_category-1], dup_bundle);
483
484         return ATTACH_PANEL_ERROR_NONE;
485 }
486
487
488
489 EXPORT_API int attach_panel_remove_content_category(attach_panel_h attach_panel, attach_panel_content_category_e content_category)
490 {
491         content_s *content_info = NULL;
492         Eina_List *l = NULL;
493
494         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
495         retv_if(!attach_panel->ui_manager, ATTACH_PANEL_ERROR_NOT_INITIALIZED);
496         retv_if(content_category < ATTACH_PANEL_CONTENT_CATEGORY_IMAGE, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
497         retv_if(content_category > ATTACH_PANEL_CONTENT_CATEGORY_VIDEO_RECORDER, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
498
499         if (EINA_TRUE == attach_panel->is_delete) {
500                 _E("Attach panel is already removed");
501                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
502         }
503
504         EINA_LIST_FOREACH(attach_panel->content_list, l, content_info) {
505                 if (content_info->innate_content_info->content_category != content_category) {
506                         continue;
507                 }
508                 bundle_free(content_info->extra_data);
509                 content_info->extra_data = NULL;
510                 _ui_manager_remove_content_category(attach_panel->ui_manager, content_info);
511                 break;
512         }
513
514         return ATTACH_PANEL_ERROR_NONE;
515 }
516
517
518
519 EXPORT_API int attach_panel_set_extra_data(attach_panel_h attach_panel, attach_panel_content_category_e content_category, bundle *extra_data)
520 {
521         app_control_h app_control = NULL;
522         ui_gadget_h ui_gadget = NULL;
523         content_s *content_info = NULL;
524         Eina_List *l = NULL;
525
526         int ret = ATTACH_PANEL_ERROR_NONE;
527         int bundle_is_op = 0;
528
529         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
530         retv_if(!attach_panel->ui_manager, ATTACH_PANEL_ERROR_NOT_INITIALIZED);
531         retv_if(content_category < ATTACH_PANEL_CONTENT_CATEGORY_IMAGE, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
532         retv_if(content_category > ATTACH_PANEL_CONTENT_CATEGORY_VIDEO_RECORDER, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
533         retv_if(!extra_data, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
534
535         bundle_foreach(extra_data, (void *) __iter_cb, &bundle_is_op);
536
537         if (bundle_is_op) {
538                 _E("bundle key is invalid value");
539                 return ATTACH_PANEL_ERROR_INVALID_PARAMETER;
540         }
541
542         EINA_LIST_FOREACH(attach_panel->content_list, l, content_info) {
543                 if (content_info->innate_content_info->content_category == content_category) {
544                         _D("add the data in %d content category", content_category);
545                         break;
546                 }
547         }
548
549         if (content_info->extra_data) {
550                 ret = _bundle_add_to_bundle(content_info->extra_data, extra_data);
551                 retv_if(ret != ATTACH_PANEL_ERROR_NONE, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
552         } else {
553                 bundle *dup_bundle = NULL;
554
555                 dup_bundle = bundle_dup(extra_data);
556                 retv_if(!dup_bundle, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
557
558                 content_info->extra_data = dup_bundle;
559         }
560
561         if (innate_content_info[content_category-1].is_ug) {
562                 if (!content_info->content) {
563                         _D("Create ug because ug is not created yet");
564                         content_info->content = _ui_manager_create_content(content_info->page, content_info, attach_panel);
565                         retv_if(!content_info->content, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
566                         if (ATTACH_PANEL_STATE_FULL == _gesture_get_state()) {
567                                 _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_MULTIPLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
568                         } else {
569                                 _content_list_send_message(attach_panel->content_list, APP_CONTROL_DATA_SELECTION_MODE, SELECTION_MODE_SINGLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
570                         }
571                 }
572
573                 ret = app_control_create(&app_control);
574                 retv_if(APP_CONTROL_ERROR_NONE != ret, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
575
576                 ui_gadget = evas_object_data_get(content_info->content, DATA_KEY_UG);
577                 if (!ui_gadget) {
578                         _E("Fail to get the ui gadget from content_info");
579                         app_control_destroy(app_control);
580                         return ATTACH_PANEL_ERROR_OUT_OF_MEMORY;
581
582                 }
583                 ug_send_message(ui_gadget, app_control);
584                 ret = app_control_destroy(app_control);
585                 retv_if(APP_CONTROL_ERROR_NONE != ret, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
586         } else {
587                 // In case of app, bundle is not used imediately.
588                 // when app is launching, bundle is used.
589         }
590
591         return ATTACH_PANEL_ERROR_NONE;
592 }
593
594
595
596 EXPORT_API int attach_panel_set_result_cb(attach_panel_h attach_panel, attach_panel_result_cb result_cb, void *user_data)
597 {
598         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
599         retv_if(!result_cb, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
600
601         if (EINA_TRUE == attach_panel->is_delete) {
602                 _E("Attach panel is already removed");
603                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
604         }
605
606         attach_panel->result_cb = result_cb;
607         attach_panel->result_data = user_data;
608
609         return ATTACH_PANEL_ERROR_NONE;
610 }
611
612
613
614 EXPORT_API int attach_panel_unset_result_cb(attach_panel_h attach_panel)
615 {
616         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
617
618         if (EINA_TRUE == attach_panel->is_delete) {
619                 _E("Attach panel is already removed");
620                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
621         }
622
623         attach_panel->result_cb = NULL;
624         attach_panel->result_data = NULL;
625
626         return ATTACH_PANEL_ERROR_NONE;
627 }
628
629
630
631 EXPORT_API int attach_panel_set_event_cb(attach_panel_h attach_panel, attach_panel_event_cb event_cb, void *user_data)
632 {
633         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
634         retv_if(!event_cb, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
635
636         if (EINA_TRUE == attach_panel->is_delete) {
637                 _E("Attach panel is already removed");
638                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
639         }
640
641         attach_panel->event_cb = event_cb;
642         attach_panel->event_data = user_data;
643
644         return ATTACH_PANEL_ERROR_NONE;
645 }
646
647
648
649 EXPORT_API int attach_panel_unset_event_cb(attach_panel_h attach_panel)
650 {
651         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
652
653         if (EINA_TRUE == attach_panel->is_delete) {
654                 _E("Attach panel is already removed");
655                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
656         }
657
658         attach_panel->event_cb = NULL;
659         attach_panel->event_data = NULL;
660
661         return ATTACH_PANEL_ERROR_NONE;
662 }
663
664
665
666 EXPORT_API int attach_panel_show(attach_panel_h attach_panel)
667 {
668         Elm_Object_Item *first_it;
669         content_s *content_info = NULL;
670         int height = 0;
671
672         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
673         retv_if(!attach_panel->ui_manager, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
674
675         if (EINA_TRUE == attach_panel->is_delete) {
676                 _E("Attach panel is already removed");
677                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
678         }
679
680         if (ATTACH_PANEL_STATE_HIDE != _gesture_get_state()) {
681                 _D("Attach panel is already shown");
682                 return ATTACH_PANEL_ERROR_NONE;
683         }
684
685         isf_control_get_recent_ime_geometry(NULL, NULL, NULL, &height);
686         if (height && height > attach_panel->transit_height) {
687                 _D("change the attach-panel's height(%d)", height);
688                 evas_object_size_hint_min_set(attach_panel->attach_panel_rect, 0, height);
689                 attach_panel->transit_height = height;
690         }
691
692         content_info = eina_list_nth(attach_panel->content_list, attach_panel->cur_page_no);
693         retv_if(!content_info, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
694
695         _toolbar_bring_in(attach_panel->toolbar, content_info->tabbar_item);
696
697         if (content_info->content) {
698                 elm_scroller_page_show(attach_panel->scroller, attach_panel->cur_page_no, 0);
699         } else {
700                 content_info->content = _ui_manager_create_content(content_info->page, content_info, attach_panel);
701                 retv_if(!content_info->content, ATTACH_PANEL_ERROR_OUT_OF_MEMORY);
702         }
703
704         _content_list_set_resume(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
705         _content_list_send_message(attach_panel->content_list, "__ATTACH_PANEL_INITIALIZE__", MODE_ENABLE, ATTACH_PANEL_CONTENT_CATEGORY_UG);
706         evas_object_show(attach_panel->ui_manager);
707
708         _gesture_show(attach_panel);
709
710         attach_panel->content_list = _list_sort_by_rua(attach_panel->content_list);
711         _grid_refresh(attach_panel->grid);
712
713         first_it = elm_gengrid_first_item_get(attach_panel->grid);
714         if (first_it) {
715                 elm_gengrid_item_show(first_it, ELM_GENGRID_ITEM_SCROLLTO_TOP);
716         }
717
718         return ATTACH_PANEL_ERROR_NONE;
719 }
720
721
722
723 EXPORT_API int attach_panel_hide(attach_panel_h attach_panel)
724 {
725         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
726         retv_if(!attach_panel->ui_manager, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
727
728         if (EINA_TRUE == attach_panel->is_delete) {
729                 _E("Attach panel is already removed");
730                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
731         }
732
733         _content_list_set_pause(attach_panel->content_list, ATTACH_PANEL_CONTENT_CATEGORY_UG);
734         _gesture_hide(attach_panel);
735
736         return ATTACH_PANEL_ERROR_NONE;
737 }
738
739
740
741 EXPORT_API int attach_panel_get_visibility(attach_panel_h attach_panel, bool *visible)
742 {
743         retv_if(!attach_panel, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
744         retv_if(!visible, ATTACH_PANEL_ERROR_INVALID_PARAMETER);
745
746         if (EINA_TRUE == attach_panel->is_delete) {
747                 _E("Attach panel is already removed");
748                 return ATTACH_PANEL_ERROR_ALREADY_DESTROYED;
749         }
750
751         if (attach_panel->rotate) {
752                 if (ATTACH_PANEL_STATE_HIDE == attach_panel->attach_panel_land_state) {
753                         *visible = false;
754                 } else {
755                         *visible = true;
756                 }
757         } else {
758                 if (ATTACH_PANEL_STATE_HIDE == attach_panel->attach_panel_port_state) {
759                         *visible = false;
760                 } else {
761                         *visible = true;
762                 }
763         }
764
765         return ATTACH_PANEL_ERROR_NONE;
766 }