Apply EFL migration of thread, common
[apps/core/preloaded/message-app.git] / main / message.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 "message.h"
18 #include <Ecore_X.h>
19 #include <ui-gadget.h>
20 #include <ui-gadget-module.h>
21 #include <sound_manager.h>
22 #include <system_info.h>
23
24 #include "msg-ui-thread-main.h"
25 #include "msg-ui-common-utility.h"
26
27 static void __rotate(app_device_orientation_e orientation, void *data);
28 static void __msg_ui_popup_warning(Evas_Object *parent, const char *msg);
29 static service_h __msg_ui_parse_sms_uri(service_h service, const char *uri);
30 static service_h __msg_ui_parse_mmsto_uri(service_h service, const char *uri);
31 static service_h __msg_ui_parse_file_uri(service_h service, const char *uri);
32 static service_h __get_service_with_new_msg(struct appdata *ad);
33 static service_h __get_service_with_msg_id(struct appdata *ad, service_h service);
34
35 void layout_cb(ui_gadget_h ug, enum ug_mode mode, void *priv);
36 void result_cb(ui_gadget_h ug, service_h result, void *priv);
37 void destroy_cb(ui_gadget_h ug, void *priv);
38
39 struct appdata *gAppData = NULL;
40
41 static void win_del(void *data, Evas_Object *obj, void *event)
42 {
43         elm_exit();
44 }
45
46 static void main_quit_cb(void *data, Evas_Object *obj, void *event_info)
47 {
48         elm_exit();
49 }
50
51 static void lang_changed(void *data)
52 {
53         D_ENTER;
54         struct appdata *ad = data;
55
56         ug_send_event(UG_EVENT_LANG_CHANGE);
57
58         msg_ui_thread_lang_changed(ad->thread_data);
59 }
60
61 static void low_battery_cb(void *data)
62 {
63         D_ENTER;
64
65         ug_send_event(UG_EVENT_LOW_BATTERY);
66 }
67
68 static void region_changed_cb(void *data)
69 {
70         D_ENTER;
71
72         ug_send_event(UG_EVENT_REGION_CHANGE);
73 }
74
75 static void device_orientation(app_device_orientation_e orientation, void *data)
76 {
77         D_ENTER;
78
79         struct appdata *ad = data;
80         if (ad == NULL || ad->win_main == NULL)
81                 return;
82
83         __rotate(orientation, data);
84 }
85
86 static void __rotate(app_device_orientation_e orientation, void *data)
87 {
88         struct appdata *ad = data;
89         int ret = 0;
90         int rot = THREAD_ROTATE_ANGLE_UNKNOWN;
91
92         switch (orientation) {
93                 case APP_DEVICE_ORIENTATION_0:
94                         rot = THREAD_ROTATE_ANGLE_PORTRAIT;
95                         ret = ug_send_event(UG_EVENT_ROTATE_PORTRAIT);
96                         break;
97                 case APP_DEVICE_ORIENTATION_180:
98                         rot = THREAD_ROTATE_ANGLE_PORTRAIT_UPSIDEDOWN;
99                         ret = ug_send_event(UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN);
100                         break;
101                 case APP_DEVICE_ORIENTATION_270:
102                         rot = THREAD_ROTATE_ANGLE_LANDSCAPE;
103                         ret = ug_send_event(UG_EVENT_ROTATE_LANDSCAPE);
104                         break;
105                 case APP_DEVICE_ORIENTATION_90:
106                         rot = THREAD_ROTATE_ANGLE_LANDSCAPE_UPSIDEDOWN;
107                         ret = ug_send_event(UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN);
108                         break;
109                 default:
110                         rot = THREAD_ROTATE_ANGLE_UNKNOWN;
111                         break;
112         }
113
114         if (rot >= 0) {
115                 msg_ui_thread_rotation_set(ad->thread_data, rot);
116                 elm_win_rotation_with_resize_set(ad->win_main, rot);
117         }
118 }
119
120 static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info)
121 {
122         evas_object_del(obj);
123         elm_exit();
124 }
125
126 static void __msg_ui_popup_warning(Evas_Object *parent, const char *msg)
127 {
128         D_ENTER;
129
130         MSG_UI_RET_IF(MSG_UI_LEVEL_ASSERT, parent == NULL || msg == NULL);
131
132         Evas_Object *layout, *pu;
133
134         evas_object_show(parent);
135
136         layout = elm_layout_add(parent);
137         elm_layout_theme_set(layout, "layout", "application", "default");
138         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
139         elm_win_resize_object_add(parent, layout);
140         evas_object_show(layout);
141
142         pu = elm_popup_add(layout);
143         MSG_UI_RETM_IF(MSG_UI_LEVEL_ASSERT, pu == NULL, "Cannot add popup object\n");
144         evas_object_size_hint_weight_set(pu, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
145         evas_object_smart_callback_add(pu , "block,clicked", _block_clicked_cb, NULL);
146
147         elm_object_text_set(pu, msg);
148         elm_popup_timeout_set(pu, 2);
149         evas_object_smart_callback_add(pu, "timeout", main_quit_cb, NULL);
150         evas_object_show(pu);
151
152         D_LEAVE;
153 }
154
155 static service_h __msg_ui_parse_sms_uri(service_h service, const char *uri)
156 {
157         D_ENTER;
158
159         char *content = NULL;
160         char *recipient = NULL;
161         char *body_text = NULL;
162
163         service_h svc_handle = NULL;
164
165         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
166                 D_EMSG("service_create() is failed !!");
167                 return NULL;
168         }
169
170         char *scheme = g_strdup(uri);
171
172         if (scheme) {
173                 strtok_r(scheme, ":", &content);
174
175                 if (content) {
176                         if (g_ascii_isdigit(content[0]) || (content[0] == '+' && g_ascii_isdigit(content[1]))) {
177                                 recipient = strtok_r(NULL, "?", &content);
178                                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
179
180                                 if (recipient)
181                                         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
182                         }
183                 }
184                 g_free(scheme);
185         } else {
186                 service_get_extra_data(service, SERVICE_DATA_TO, &recipient);
187                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
188                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
189         }
190
191         /* Add body text */
192         service_get_extra_data(service, SERVICE_DATA_TEXT, &body_text);
193         if (body_text) {
194                 D_MSG("APPSVC BODY_TEXT = [%s]", body_text);
195                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_BODY, body_text);
196         }
197
198         D_LEAVE;
199         return svc_handle;
200 }
201
202 static service_h __msg_ui_parse_mmsto_uri(service_h service, const char *uri)
203 {
204         D_ENTER;
205
206         char *content = NULL;
207         char *recipient = NULL;
208         char *body_text = NULL;
209         char *subject = NULL;
210         char *attachment = NULL;
211         char *cc = NULL;
212
213         service_h svc_handle = NULL;
214
215         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
216                 D_EMSG("service_create() is failed !!");
217                 return NULL;
218         }
219
220         char *scheme = g_strdup(uri);
221
222         if (scheme) {
223                 strtok_r(scheme, ":", &content);
224
225                 if (content) {
226                         if (g_ascii_isdigit(content[0]) || (content[0] == '+' && g_ascii_isdigit(content[1]))) {
227                                 recipient = strtok_r(NULL, "?", &content);
228                                 cc = strtok_r(NULL, "&", &content);
229                                 if (cc)
230                                         strtok_r(NULL, "=", &cc);
231
232                                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
233                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
234                         }
235                 }
236                 g_free(scheme);
237         } else {
238                 service_get_extra_data(service, SERVICE_DATA_TO, &recipient);
239                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
240                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
241         }
242
243         /* Add body text */
244         service_get_extra_data(service, SERVICE_DATA_TEXT, &body_text);
245         if (body_text) {
246                 D_MSG("APPSVC BODY_TEXT = [%s]", body_text);
247                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_BODY, body_text);
248         }
249
250         /* Add subject */
251         service_get_extra_data(service, SERVICE_DATA_SUBJECT, &subject);
252         if (subject) {
253                 D_MSG("APPSVC SUBJECT = [%s]", subject);
254                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_SUBJECT, subject);
255         }
256
257         /* Add attachment */
258         service_get_extra_data(service, MSG_BUNDLE_KEY_ATTACHFILE, &attachment);
259         if (attachment) {
260                 D_MSG("APPSVC ATTACHMENT = [%s]", attachment);
261                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_ATTACHFILE, attachment);
262         }
263
264         D_LEAVE;
265
266         return svc_handle;
267 }
268
269 static service_h __msg_ui_parse_file_uri(service_h service, const char *uri)
270 {
271         D_ENTER;
272
273         char *content = NULL;
274         char attachment[DEF_IMG_PATH_LEN] = {0, };
275         int i = 0;
276         int len = 0;
277
278         service_h svc_handle = NULL;
279
280         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
281                 D_EMSG("service_create() is failed !!");
282                 return NULL;
283         }
284
285         char *scheme = g_strdup(uri);
286
287         if (scheme) {
288                 strtok_r(scheme, ":", &content);
289                 D_MSG("content = [%s]", content);
290
291                 if (content) {
292                         len = strlen(content) - 2;
293                         if (len <= 0) {
294                                 D_EMSG("len is less than 0 !!");
295                                 service_destroy(svc_handle);
296                                 g_free(scheme);
297                                 return NULL;
298                         }
299
300                         /* Remove '//' from content string */
301                         for (i = 0; i < len; i++) {
302                                 attachment[i] = content[i+2];
303                         }
304
305                         if (attachment[0] != '\0') {
306                                 D_MSG("APPSVC ATTACHMENT = [%s]", attachment);
307                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_ATTACHFILE, attachment);
308                         }
309                 }
310                 g_free(scheme);
311         } else {
312                 D_EMSG("scheme is NULL!!");
313                 service_destroy(svc_handle);
314                 return NULL;
315         }
316
317         D_LEAVE;
318
319         return svc_handle;
320 }
321
322 static service_h __get_service_app_svc_op(const char *operation, service_h service)
323 {
324         D_ENTER;
325
326         if (service == NULL || operation == NULL)
327                 return NULL;
328
329         char *uri = NULL;
330         char *recipient = NULL;
331         char *body_text = NULL;
332         char *attachment = NULL;
333         char *subject = NULL;
334
335         service_h svc_handle = NULL;
336
337         if (g_strcmp0(operation, SERVICE_OPERATION_SEND) == 0) {
338                 service_get_uri(service, &uri);
339                 D_MSG("APPSVC URI = [%s]", uri);
340
341                 if (uri) {
342                         if (g_str_has_prefix(uri, MSG_BUNDLE_VALUE_MMSTO_URI)) {  /* MMS URI */
343                                 svc_handle = __msg_ui_parse_mmsto_uri(service, uri);
344                         } else if (g_str_has_prefix(uri, MSG_BUNDLE_VALUE_FILE_URI)) {
345                                 /* file URI */
346                                 svc_handle = __msg_ui_parse_file_uri(service, uri);
347                                 if (svc_handle == NULL) {
348                                         D_MSG("cb is NULL");
349                                         return NULL;
350                                 }
351                         } else {
352                                 D_MSG("Not supported mime type");
353                                 return NULL;
354                         }
355                 } else {
356                         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
357                                 D_EMSG("service_create() is failed !!");
358                                 return NULL;
359                         }
360
361                         /* Add recipient number */
362                         service_get_extra_data(service, SERVICE_DATA_TO, &recipient);
363                         if (recipient) {
364                                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
365                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
366                         }
367
368                         /* Add body text */
369                         service_get_extra_data(service, SERVICE_DATA_TEXT, &body_text);
370                         if (body_text) {
371                                 D_MSG("APPSVC BODY_TEXT = [%s]", body_text);
372                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_BODY, body_text);
373                         }
374
375                         /* Add subject */
376                         service_get_extra_data(service, SERVICE_DATA_SUBJECT, &subject);
377                         if (subject) {
378                                 D_MSG("APPSVC SUBJECT = [%s]", subject);
379                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_SUBJECT, subject);
380                         }
381
382                         /* Add attachment */
383                         service_get_extra_data(service, MSG_BUNDLE_KEY_ATTACHFILE, &attachment);
384                         if (attachment) {
385                                 D_MSG("APPSVC ATTACHMENT = [%s]", attachment);
386                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_ATTACHFILE, attachment);
387                         }
388                 }
389
390                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TYPE, MSG_BUNDLE_VALUE_COMPOSE);
391
392         } else if (g_strcmp0(operation, SERVICE_OPERATION_SEND_TEXT) == 0) {
393                 service_get_uri(service, &uri);
394                 D_MSG("APPSVC URI = [%s]", uri);
395
396                 if (uri) {
397                         if (g_str_has_prefix(uri, MSG_BUNDLE_VALUE_SMS_URI)) {  /* SMS URI */
398                                 svc_handle = __msg_ui_parse_sms_uri(service, uri);
399                         } else {
400                                 D_MSG("Not supported mime type");
401                                 return NULL;
402                         }
403                 } else {
404                         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
405                                 D_EMSG("service_create() is failed !!");
406                                 return NULL;
407                         }
408
409                         /* Add body text */
410                         service_get_extra_data(service, SERVICE_DATA_TEXT, &body_text);
411                         if (body_text) {
412                                 D_MSG("APPSVC BODY_TEXT = [%s]", body_text);
413                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_BODY, body_text);
414                         }
415
416                         /* Add recipient number */
417                         service_get_extra_data(service, SERVICE_DATA_TO, &recipient);
418                         if (recipient) {
419                                 D_MSG("APPSVC RECIPIENT = [%s]", recipient);
420                                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TO, recipient);
421                         }
422                 }
423
424                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TYPE, MSG_BUNDLE_VALUE_COMPOSE);
425         } else if (g_strcmp0(operation, SERVICE_OPERATION_DEFAULT) == 0) {
426                 char *key_type = NULL;
427
428                 service_get_extra_data(service, MSG_BUNDLE_KEY_TYPE, &key_type);
429                 if (g_strcmp0(key_type, MSG_BUNDLE_VALUE_MSG_ID) == 0) {
430                         msg_error_t err = MSG_SUCCESS;
431                         msg_struct_t count_info = msg_create_struct(MSG_STRUCT_COUNT_INFO);
432                         int unread_cnt = 0;
433
434                         err = msg_count_message(gAppData->msgHandle, MSG_INBOX_ID, count_info);
435                         if (err != MSG_SUCCESS) {
436                                 msg_release_struct(&count_info);
437                                 return NULL;
438                         }
439
440                         msg_get_int_value(count_info, MSG_COUNT_INFO_UNREAD_INT, &unread_cnt);
441                         if (unread_cnt == 1)
442                                 svc_handle = __get_service_with_msg_id(gAppData, service);
443
444                         msg_release_struct(&count_info);
445                 }
446         }
447
448         D_LEAVE;
449
450         return svc_handle;
451 }
452
453 static service_h __get_service_with_new_msg(struct appdata *ad)
454 {
455         D_ENTER;
456
457         msg_error_t err = MSG_SUCCESS;
458         msg_struct_list_s peerList;
459         msg_struct_t sort_rule_t = msg_create_struct(MSG_STRUCT_SORT_RULE);
460         service_h svc_handle = NULL;
461
462         int i = 0;
463         int new_sms_cnt = 0;
464         int new_mms_cnt = 0;
465         int unreadCnt = 0;
466         char buf[DEF_BUF_LEN_L] = {'0',};
467         char buf_contact[DEF_BUF_LEN] = {'0',};
468
469         msg_set_int_value(sort_rule_t, MSG_SORT_RULE_SORT_TYPE_INT, MSG_SORT_BY_THREAD_DATE);
470         msg_set_bool_value(sort_rule_t, MSG_SORT_RULE_ACSCEND_BOOL, false);
471
472         vconf_get_int(VCONFKEY_MESSAGE_RECV_SMS_STATE, &new_sms_cnt);
473         vconf_get_int(VCONFKEY_MESSAGE_RECV_MMS_STATE, &new_mms_cnt);
474
475         err = msg_get_thread_view_list(ad->msgHandle, sort_rule_t, &peerList);
476         if (err != MSG_SUCCESS) {
477                 msg_release_struct(&sort_rule_t);
478                 return NULL;
479         }
480
481         if (peerList.nCount <= 0) {
482                 msg_release_list_struct(&peerList);
483                 msg_release_struct(&sort_rule_t);
484                 return NULL;
485         }
486
487         for (i=0; i<peerList.nCount; i++){
488                 msg_get_int_value(peerList.msg_struct_info[i], MSG_THREAD_UNREAD_COUNT_INT, &unreadCnt);
489                 if (unreadCnt > 0)
490                         break;
491         }
492
493         if(i >= peerList.nCount) {
494                 msg_release_list_struct(&peerList);
495                 msg_release_struct(&sort_rule_t);
496                 return NULL;
497         }
498
499         msg_get_int_value(peerList.msg_struct_info[i], MSG_THREAD_UNREAD_COUNT_INT, &unreadCnt);
500         if(unreadCnt == new_sms_cnt+new_mms_cnt){
501                 if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
502                         D_EMSG("service_create() is failed !!");
503                         msg_release_list_struct(&peerList);
504                         msg_release_struct(&sort_rule_t);
505                         return NULL;
506                 }
507
508                 msg_struct_list_s *addrList = NULL;
509                 int thread_id = 0;
510                 int contact_id = 0;
511                 char strName[DEF_THREAD_NAME_LEN+1] = {0,};
512                 char strNumber[DEF_THREAD_ADDR_LEN+1] = {0,};
513
514                 msg_get_int_value(peerList.msg_struct_info[i], MSG_THREAD_ID_INT, &thread_id);
515                 msg_get_list_handle(peerList.msg_struct_info[i], MSG_MESSAGE_ADDR_LIST_STRUCT, (void **)&addrList);
516
517                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_TYPE, MSG_BUNDLE_VALUE_NEW_MSG);
518                 snprintf(buf, DEF_BUF_LEN_L, "%d", thread_id);
519                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_ID, buf);
520                 msg_get_str_value(peerList.msg_struct_info[i], MSG_THREAD_NAME_STR, strName, DEF_THREAD_NAME_LEN);
521                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_NAME, strName);
522
523                 msg_get_str_value(addrList->msg_struct_info[0], MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, DEF_THREAD_ADDR_LEN);
524                 msg_get_int_value(addrList->msg_struct_info[0], MSG_ADDRESS_INFO_CONTACT_ID_INT, &contact_id);
525
526                 snprintf(buf_contact, DEF_BUF_LEN, "%d", contact_id);
527                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_ADDRESS, strNumber);
528                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_CONTACT_ID, buf_contact);
529         }
530
531         msg_release_struct(&sort_rule_t);
532         msg_release_list_struct(&peerList);
533
534         D_LEAVE;
535
536         return svc_handle;
537 }
538
539 static service_h __get_service_with_msg_id(struct appdata *ad, service_h service)
540 {
541         D_ENTER;
542
543         service_h svc_handle = NULL;
544
545         if (service_create(&svc_handle) < 0 || svc_handle == NULL) {
546                 D_EMSG("service_create() is failed !!");
547                 return NULL;
548         }
549
550         int msg_id = 0;
551         char *msg_id_str = NULL;
552         service_get_extra_data(service, MSG_BUNDLE_KEY_MSG_ID, &msg_id_str);
553
554         if (!msg_id_str) {
555                 service_destroy(svc_handle);
556                 return NULL;
557         }
558
559         msg_id = atoi(msg_id_str);
560
561         if (msg_id <= 0) {
562                 service_destroy(svc_handle);
563                 return NULL;
564         }
565
566         msg_struct_t msgInfo = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
567         msg_struct_t sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT);
568         msg_error_t err = MSG_SUCCESS;
569
570         int thread_id = 0;
571         int contact_id = 0;
572         char buf_thread[DEF_BUF_LEN_S] = {0,};
573         char buf_contact[DEF_BUF_LEN_S] = {0,};
574
575         msg_struct_list_s *addr_list = NULL;
576         char strNumber[DEF_THREAD_ADDR_LEN + 1] = {0,};
577         char strName[DEF_THREAD_NAME_LEN + 1] = {0,};
578
579         err = msg_get_message(ad->msgHandle, (msg_message_id_t)msg_id, msgInfo, sendOpt);
580
581         if (err != MSG_SUCCESS) {
582                 service_destroy(svc_handle);
583                 msg_release_struct(&msgInfo);
584                 msg_release_struct(&sendOpt);
585                 return NULL;
586         }
587
588         msg_get_int_value(msgInfo, MSG_MESSAGE_THREAD_ID_INT, &thread_id);
589         snprintf(buf_thread, sizeof(buf_thread), "%d", thread_id);
590
591         msg_get_list_handle(msgInfo, MSG_MESSAGE_ADDR_LIST_STRUCT, (void **)&addr_list);
592
593         msg_get_str_value(addr_list->msg_struct_info[0], MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, DEF_THREAD_ADDR_LEN);
594         msg_get_str_value(addr_list->msg_struct_info[0], MSG_ADDRESS_INFO_DISPLAYNAME_STR, strName, DEF_THREAD_NAME_LEN);
595         msg_get_int_value(addr_list->msg_struct_info[0], MSG_ADDRESS_INFO_CONTACT_ID_INT, &contact_id);
596         snprintf(buf_contact, sizeof(buf_contact), "%d", contact_id);
597
598         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_ID, buf_thread);
599         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_NAME, strName);
600         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_ADDRESS, strNumber);
601         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_CONTACT_ID, buf_contact);
602
603         msg_release_struct(&msgInfo);
604         msg_release_struct(&sendOpt);
605
606         D_LEAVE;
607         return svc_handle;
608 }
609
610 static Evas_Object* create_win(const char *name)
611 {
612         D_ENTER;
613
614         Evas_Object *eo;
615         int w, h;
616
617         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
618         if (eo) {
619                 elm_win_title_set(eo, name);
620                 evas_object_smart_callback_add(eo, "delete,request", win_del, NULL);
621                 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
622                 evas_object_resize(eo, w, h);
623                 elm_win_conformant_set(eo, EINA_TRUE);
624         }
625
626         D_LEAVE;
627         return eo;
628 }
629
630 void layout_cb(ui_gadget_h ug, enum ug_mode mode, void *priv)
631 {
632         D_ENTER;
633
634         struct appdata *ad;
635         Evas_Object *base, *win;
636
637         if (!ug || !priv)
638                 return;
639
640         ad = priv;
641
642         base = ug_get_layout(ug);
643
644         if (!base){
645                 ug_destroy(ug);
646                 return;
647         }
648
649         win = ug_get_window();
650
651         switch (mode) {
652                 case UG_MODE_FULLVIEW:
653                         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
654                         elm_win_resize_object_add(win, base);
655                         evas_object_show(base);
656                         break;
657                 case UG_MODE_FRAMEVIEW:
658                 default:
659                         break;
660         }
661
662         D_LEAVE;
663 }
664
665 void result_cb(ui_gadget_h ug, service_h result, void *priv)
666 {
667         D_ENTER;
668
669         MSG_UI_RET_IF(MSG_UI_LEVEL_ERR, !ug || !priv);
670
671         struct appdata *ad = priv;
672
673         PMSG_THREAD_DATA pData = (PMSG_THREAD_DATA)ad->thread_data;
674         PMSG_THREAD_LIST_DATA pListData = NULL;
675         char *buf = NULL;
676         char *str_result = NULL;
677
678         service_get_extra_data(result, MSG_BUNDLE_KEY_RESULT, &str_result);
679         if (pData == NULL) {
680                 if (!g_strcmp0(str_result, MSG_BUNDLE_VALUE_DEL_ALL))
681                         ug_destroy(ug);
682
683                 elm_exit();
684                 return;
685         }
686
687         pListData = msg_ui_thread_get_current_list();
688
689         if (!g_strcmp0(str_result, MSG_BUNDLE_VALUE_DEL_ALL)) {
690                 ug_destroy(ug);
691
692                 if (pListData) {
693                         int del_id = 0;
694
695                         if (pListData->app_data_type == THREAD_LIST_APP_DATA_MSG) {
696                                 service_get_extra_data(result, MSG_BUNDLE_KEY_MSG_ID, &buf);
697                                 if (buf) {
698                                         del_id = atoi(buf);
699                                         msg_ui_thread_list_msg_item_delete(pListData, del_id);
700                                 }
701                         } else {
702                                 service_get_extra_data(result, MSG_BUNDLE_KEY_THREAD_ID, &buf);
703                                 if (buf) {
704                                         del_id = atoi(buf);
705                                         msg_ui_thread_list_item_delete(pListData, del_id);
706                                 }
707                         }
708
709                         if (pData->isRotate == true) {
710                                 if (!pData->split_data) {
711                                         msg_ui_thread_create_split_data();
712                                         msg_ui_thread_splitview_launch(pData, pData->split_data);
713                                 }
714                         } else {
715                                 elm_object_part_content_set(pData->panes, "left", pData->layout_main);
716                                 elm_object_part_content_unset(pData->panes, "right");
717                                 elm_panes_content_left_size_set(pData->panes, 1.0);
718                         }
719
720                         pListData->sel_gen_item = NULL;
721                         pListData->sel_thread_id = 0;
722                         pListData->sel_msg_id = 0;
723                         ad->composer_ug = NULL;
724                         ad->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
725                 }
726         } else {
727                 int update_id = 0;
728
729                 if (pListData->app_data_type == THREAD_LIST_APP_DATA_MSG) {
730                         service_get_extra_data(result, MSG_BUNDLE_KEY_MSG_ID, &buf);
731                         if (buf) {
732                                 update_id = atoi(buf);
733                                 msg_ui_thread_list_msg_item_update(pListData, update_id);
734                         }
735                 } else {
736                         service_get_extra_data(result, MSG_BUNDLE_KEY_THREAD_ID, &buf);
737                         if (buf) {
738                                 update_id = atoi(buf);
739                                 msg_ui_thread_list_item_update(pListData, update_id);
740                                 pListData->sel_thread_id = update_id;
741                         }
742                 }
743         }
744
745         D_LEAVE;
746 }
747
748 void destroy_cb(ui_gadget_h ug, void *priv)
749 {
750         D_ENTER;
751
752         MSG_UI_RET_IF(MSG_UI_LEVEL_ERR, !ug || !priv);
753
754         struct appdata *ad = (struct appdata *)priv;
755         int ug_type = ad->ug_type;
756
757         if (ug == ad->composer_ug) {
758                 ug_destroy(ug);
759                 ad->composer_ug = NULL;
760                 ad->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
761         }
762
763         if (ad->layout_main) {
764                 PMSG_THREAD_DATA pData = (PMSG_THREAD_DATA)ad->thread_data;
765                 PMSG_THREAD_LIST_DATA pListData = NULL;
766
767                 pListData = msg_ui_thread_get_current_list();
768                 if (pListData == NULL) {
769                         elm_exit();
770                         return;
771                 }
772
773                 if (pData) {
774                         if (pData->isRotate == true) {
775                                 if (!pData->split_data) {
776                                         msg_ui_thread_create_split_data();
777                                         msg_ui_thread_splitview_launch(pData, pData->split_data);
778                                 }
779                                 if (ug_type == MSG_COMPOSER_UG_TYPE_VIEWER) {
780                                         msg_ui_thread_cancel_search_mode(pListData);
781                                         elm_win_lower(pData->win_main);
782                                 }
783                         } else {
784                                 elm_object_part_content_set(pData->panes, "left", pData->layout_main);
785                                 elm_object_part_content_unset(pData->panes, "right");
786                                 elm_panes_content_left_size_set(pData->panes, 1.0);
787                         }
788                 }
789
790                 if (pListData->sel_thread_id > 0)
791                         msg_ui_thread_list_item_update(pListData, pListData->sel_thread_id);
792
793                 if (pListData->sel_msg_id > 0)
794                         msg_ui_thread_list_msg_item_update(pListData, pListData->sel_msg_id);
795
796                 pListData->sel_gen_item = NULL;
797                 pListData->sel_thread_id = 0;
798                 pListData->sel_msg_id = 0;
799
800                 pListData->view_mode = THREAD_NORMAL_VIEW;
801         } else {
802                 elm_exit();
803         }
804 }
805
806 int msg_ui_load_composer_ug(service_h svc_handle, MessageComposerUgType ug_type)
807 {
808         D_ENTER;
809
810         if (!gAppData)
811                 return MSG_UI_RET_ERR;
812
813         if (gAppData->composer_ug) {
814                 if (ug_type == MSG_COMPOSER_UG_TYPE_COMPOSER && gAppData->ug_type == MSG_COMPOSER_UG_TYPE_VIEWER) {
815                         ug_destroy(gAppData->composer_ug);
816                         gAppData->composer_ug = NULL;
817                         gAppData->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
818
819                         service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_FROM, MSG_BUNDLE_VALUE_INTERNAL);
820                         if (ug_type == MSG_COMPOSER_UG_TYPE_COMPOSER)
821                                 gAppData->composer_ug = ug_create(NULL, MSG_COMPOSER_UG_NAME, UG_MODE_FULLVIEW, svc_handle, &gAppData->cbs);
822                         else
823                                 gAppData->composer_ug = ug_create(NULL, MSG_COMPOSER_UG_NAME, UG_MODE_FRAMEVIEW, svc_handle, &gAppData->cbs);
824                 } else {
825                         ug_send_message(gAppData->composer_ug, svc_handle);
826                 }
827         } else {
828                 service_add_extra_data(svc_handle, MSG_BUNDLE_KEY_FROM, MSG_BUNDLE_VALUE_INTERNAL);
829                 if (ug_type == MSG_COMPOSER_UG_TYPE_COMPOSER)
830                         gAppData->composer_ug = ug_create(NULL, MSG_COMPOSER_UG_NAME, UG_MODE_FULLVIEW, svc_handle, &gAppData->cbs);
831                 else
832                         gAppData->composer_ug = ug_create(NULL, MSG_COMPOSER_UG_NAME, UG_MODE_FRAMEVIEW, svc_handle, &gAppData->cbs);
833         }
834
835         if (!gAppData->composer_ug)
836                 return MSG_UI_RET_ERR;
837
838         gAppData->ug_type = ug_type;
839
840         if (ug_type == MSG_COMPOSER_UG_TYPE_VIEWER) {
841                 PMSG_THREAD_DATA pData = (PMSG_THREAD_DATA)gAppData->thread_data;
842                 Evas_Object * layout = (Evas_Object *)ug_get_layout(gAppData->composer_ug);
843                 elm_object_part_content_set(pData->panes, "right", layout);
844                 msg_ui_thread_destroy_split_data(pData->split_data);
845
846                 if (pData->isRotate == false) {
847                         elm_object_part_content_unset(pData->panes, "left");
848                         elm_panes_content_left_size_set(pData->panes, 0.0);
849                         evas_object_hide(pData->layout_main);
850                 }
851         }
852         D_LEAVE;
853         return MSG_UI_RET_SUCCESS;
854 }
855
856 Evas_Object *msg_ui_get_composer_ug_viewer_layout(void)
857 {
858         D_ENTER;
859
860         if (!gAppData || !gAppData->composer_ug)
861                 return NULL;
862
863         if (gAppData->ug_type != MSG_COMPOSER_UG_TYPE_VIEWER)
864                 return NULL;
865
866         Evas_Object * layout = (Evas_Object *)ug_get_layout(gAppData->composer_ug);
867
868         D_LEAVE;
869
870         return layout;
871 }
872
873 void msg_ui_destroy_composer_ug(void)
874 {
875         if (!gAppData || !gAppData->composer_ug)
876                 return;
877
878         ug_destroy(gAppData->composer_ug);
879
880         PMSG_THREAD_DATA pData = (PMSG_THREAD_DATA)gAppData->thread_data;
881         PMSG_THREAD_LIST_DATA pListData = msg_ui_thread_get_current_list();
882
883         if (pListData) {
884                 if (pData->isRotate == true) {
885                         if (!pData->split_data) {
886                                 msg_ui_thread_create_split_data();
887                                 msg_ui_thread_splitview_launch(pData, pData->split_data);
888                         }
889                 }
890
891                 pListData->sel_gen_item = NULL;
892                 pListData->sel_thread_id = 0;
893                 pListData->sel_msg_id = 0;
894                 gAppData->composer_ug = NULL;
895                 gAppData->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
896         }
897 }
898
899 static bool app_create(void *data)
900 {
901         /* return TRUE : success, return FALSE : not to run main loop */
902
903         D_ENTER;
904
905         MSG_UI_RETV_IF(MSG_UI_LEVEL_ERR, !data, MSG_UI_RET_ERR);
906
907         struct appdata *ad = data;
908         Evas_Object *win;
909         sound_manager_error_e err = SOUND_MANAGER_ERROR_NONE;
910
911         /* create window */
912         win = create_win(MESSAGE_PKGNAME);
913         if (win == NULL)
914                 return FALSE;
915
916         ad->win_main = win;
917
918         ad->bg = elm_bg_add(ad->win_main);
919         evas_object_size_hint_weight_set(ad->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
920         elm_win_resize_object_add(ad->win_main, ad->bg);
921
922         ad->conform = elm_conformant_add(win);
923         if (ad->conform == NULL)
924                 return FALSE;
925
926         evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
927         elm_win_resize_object_add(win, ad->conform);
928         evas_object_show(ad->conform);
929
930         err = sound_manager_set_session_type(SOUND_SESSION_TYPE_SHARE);
931         if (err != SOUND_MANAGER_ERROR_NONE)
932                 D_MSG("sound_manager_set_session_type is failed, ret = [%d]", err);
933
934         UG_INIT_EFL(ad->win_main, UG_OPT_INDICATOR_ENABLE);
935         elm_win_indicator_mode_set(ad->win_main, ELM_WIN_INDICATOR_SHOW);
936         __rotate(app_get_device_orientation(), ad);
937
938         ad->cbs.layout_cb = layout_cb;
939         ad->cbs.result_cb = result_cb;
940         ad->cbs.destroy_cb = destroy_cb;
941         ad->cbs.priv = (void *)ad;
942
943         gAppData = ad; // Set global app data pointer;
944
945         D_LEAVE;
946         return TRUE;
947 }
948
949 static void app_terminate(void *data)
950 {
951         D_ENTER;
952
953         MSG_UI_RETM_IF(MSG_UI_LEVEL_ERR, !data, "data is null");
954
955         struct appdata *ad = data;
956         msg_error_t     err;
957
958         ug_destroy_all();
959
960         if (ad->thread_data)
961                 msg_ui_thread_deinit_thread_data(ad->thread_data);
962
963         if (ad->msgHandle) {
964                 err = msg_close_msg_handle(&ad->msgHandle);
965                 D_MSG("msg_close_msg_handle, ret = [%d]", err);
966         }
967
968         D_LEAVE;
969 }
970
971 static void app_pause(void *data)
972 {
973         D_ENTER;
974
975         msg_ui_thread_set_app_state(MSG_UI_STATE_PAUSE);
976         ug_pause();
977
978         D_LEAVE;
979 }
980
981 static void app_resume(void *data)
982 {
983         D_ENTER;
984         msg_ui_thread_set_app_state(MSG_UI_STATE_RUNNING);
985
986         ug_resume();
987
988         D_LEAVE;
989 }
990
991 static void app_service(service_h service, void *data)
992 {
993         D_ENTER;
994         MSG_UI_RETM_IF(MSG_UI_LEVEL_ERR, !data, "data is NULL");
995
996         struct appdata *ad = data;
997         service_h svc_handle = NULL;
998         msg_error_t err = MSG_SUCCESS;
999         msg_handle_t msgHandle = NULL;
1000         bool isDefaultView = false;
1001
1002         char *operation = NULL;
1003         char *cvalue = NULL;
1004         int ret = SYSTEM_INFO_ERROR_NONE;
1005
1006         ret = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &cvalue);
1007         if (ret == SYSTEM_INFO_ERROR_NONE && cvalue != NULL) {
1008                 if (g_strcmp0(cvalue, "Emulator") == 0) {
1009                         D_MSG("Not support in Emulator !!");
1010                         g_free(cvalue);
1011                         cvalue = NULL;
1012
1013                         service_h reply;
1014
1015                         int ret = service_create(&reply);
1016                         if (ret != SERVICE_ERROR_NONE) {
1017                                 D_EMSG("service_create() is failed : ret = %d", ret);
1018                         } else {
1019                                 service_reply_to_launch_request(reply, service, SERVICE_RESULT_CANCELED);
1020                                 service_destroy(reply);
1021                         }
1022
1023                         /* Exit application because it is not supported in Emulator. */
1024                         elm_exit();
1025                         return;
1026                 }
1027         }
1028
1029         if (cvalue) {
1030                 g_free(cvalue);
1031                 cvalue = NULL;
1032         }
1033
1034         ug_resume();
1035
1036         if (!ad->msgHandle) {
1037                 err = msg_open_msg_handle(&msgHandle);
1038                 if (err != MSG_SUCCESS) {
1039                         MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "msg_open_msg_handle failed, Error=[%d]\n", err);
1040                         __msg_ui_popup_warning(ad->win_main,  dgettext("sys_string", "IDS_COM_POP_SERVICE_UNAVAILABLE"));
1041                         return;
1042                 }
1043                 ad->msgHandle = msgHandle;
1044         }
1045
1046         if (service) {
1047                 service_get_operation(service, &operation);
1048                 if (operation) {
1049                         svc_handle = __get_service_app_svc_op(operation, service);
1050                 } else {
1051                         char *key_type = NULL;
1052
1053                         service_get_extra_data(service, MSG_BUNDLE_KEY_TYPE, &key_type);
1054                         if (g_strcmp0(key_type, MSG_BUNDLE_VALUE_COMPOSE) == 0) {
1055                                 service_clone(&svc_handle, service);
1056                         } else if (g_strcmp0(key_type, MSG_BUNDLE_VALUE_NEW_MSG) == 0) {
1057                                 svc_handle = __get_service_with_new_msg(ad);
1058                         } else if (g_strcmp0(key_type, MSG_BUNDLE_VALUE_MSG_ID) == 0) {
1059                                 svc_handle = __get_service_with_msg_id(ad, service);
1060                         } else {
1061                                 char *mime_type = NULL;
1062
1063                                 service_get_extra_data(service, AUL_K_MIME_TYPE, &mime_type);
1064                                 if (g_strcmp0(mime_type, MSG_BUNDLE_VALUE_SMS_URI) == 0)
1065                                         svc_handle = __msg_ui_parse_sms_uri(service, NULL);
1066                                 else if (g_strcmp0(mime_type, MSG_BUNDLE_VALUE_MMSTO_URI) == 0)
1067                                         svc_handle = __msg_ui_parse_mmsto_uri(service, NULL);
1068                                 else
1069                                         isDefaultView = true;
1070                         }
1071                 }
1072
1073                 if (!svc_handle)
1074                         isDefaultView = true;
1075         } else {
1076                 isDefaultView = true;
1077         }
1078
1079         if (isDefaultView) {
1080                 MSG_UI_DEBUG(MSG_UI_LEVEL_DEBUG, "show DefaultView");
1081                 if (ad->composer_ug) {
1082                         ug_destroy(ad->composer_ug);
1083                         ad->composer_ug = NULL;
1084                         ad->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
1085                 }
1086
1087                 if (!ad->thread_data)
1088                         ad->thread_data = msg_ui_thread_init_thread_data(ad);
1089
1090                 if (!ad->layout_main) {
1091                         ad->layout_main = msg_ui_thread_create_layout_main(ad->thread_data);
1092                         evas_object_size_hint_weight_set(ad->layout_main, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1093                         elm_object_content_set(ad->conform, ad->layout_main);
1094
1095                         msg_ui_thread_load_thread_view(ad->thread_data, service);
1096                 } else {
1097                         msg_ui_thread_reset_thread_view(ad->thread_data, service);
1098                 }
1099                 __rotate(app_get_device_orientation(), ad);
1100         } else {
1101                 MSG_UI_DEBUG(MSG_UI_LEVEL_DEBUG, "show app-service view");
1102                 /* If message app is called by app-service to display composer view,
1103                  * list view should be destroyed because previous screen should be displayed
1104                  * when user tap back button.
1105                  */
1106                  MessageComposerUgType ug_type = MSG_COMPOSER_UG_TYPE_NONE;
1107
1108                 if (operation != NULL) {
1109                         int i = 0;
1110                         PMSG_THREAD_DATA pData = (PMSG_THREAD_DATA)ad->thread_data;
1111
1112                         if (g_strcmp0(operation, SERVICE_OPERATION_SEND) == 0 ||
1113                                 g_strcmp0(operation, SERVICE_OPERATION_SEND_TEXT) == 0) {
1114                                 if (ad->layout_main) {
1115                                         /* content unset composer */
1116                                         if (ad->ug_type == MSG_COMPOSER_UG_TYPE_VIEWER) {
1117                                                 if (pData)
1118                                                         elm_object_part_content_unset(pData->panes, "right");
1119                                         }
1120
1121                                         if (pData) {
1122                                                 for (i = MSG_THREAD_LIST_MAX_COUNT-1; i >= 0; i--) {
1123                                                         if (pData->list_data[i] != NULL) {
1124                                                                 msg_ui_thread_destroy_thread_list_data(pData->list_data[i]);
1125                                                         }
1126                                                 }
1127                                         }
1128                                         evas_object_del(ad->layout_main);
1129                                         ad->layout_main = NULL;
1130                                 }
1131                                 ug_type = MSG_COMPOSER_UG_TYPE_COMPOSER;
1132                         } else if (g_strcmp0(operation, SERVICE_OPERATION_DEFAULT) == 0) {
1133                                 char *key_type = NULL;
1134
1135                                 service_get_extra_data(service, MSG_BUNDLE_KEY_TYPE, &key_type);
1136                                 if (g_strcmp0(key_type, MSG_BUNDLE_VALUE_MSG_ID) == 0) {
1137                                         if (ad->layout_main) {
1138                                                 /* content unset composer */
1139                                                 if (ad->ug_type == MSG_COMPOSER_UG_TYPE_VIEWER) {
1140                                                         if (pData)
1141                                                                 elm_object_part_content_unset(pData->panes, "right");
1142                                                 }
1143
1144                                                 if (pData) {
1145                                                         for (i = MSG_THREAD_LIST_MAX_COUNT-1; i >= 0; i--) {
1146                                                                 if (pData->list_data[i] != NULL) {
1147                                                                         msg_ui_thread_destroy_thread_list_data(pData->list_data[i]);
1148                                                                 }
1149                                                         }
1150                                                 }
1151                                                 evas_object_del(ad->layout_main);
1152                                                 ad->layout_main = NULL;
1153                                         }
1154                                         ug_type = MSG_COMPOSER_UG_TYPE_VIEWER;
1155                                 }
1156                         }
1157                 }
1158
1159                 if (ad->composer_ug) {
1160                         ug_destroy(ad->composer_ug);
1161                         ad->composer_ug = NULL;
1162                         ad->ug_type = MSG_COMPOSER_UG_TYPE_NONE;
1163                 }
1164
1165                 ad->composer_ug = ug_create(NULL, MSG_COMPOSER_UG_NAME, UG_MODE_FULLVIEW, svc_handle, &ad->cbs);
1166                 ad->ug_type = ug_type;
1167         }
1168
1169         if (svc_handle)
1170                 service_destroy(svc_handle);
1171
1172         if (ad->win_main) {
1173                 evas_object_show(ad->win_main);
1174                 elm_win_activate(ad->win_main);
1175         }
1176
1177         if (ad->layout_main == NULL && ad->composer_ug == NULL)
1178                 elm_exit();
1179
1180         D_LEAVE;
1181 }
1182
1183 int main(int argc, char *argv[])
1184 {
1185         D_ENTER;
1186
1187         struct appdata ad;
1188         memset(&ad, 0x0, sizeof(struct appdata));
1189
1190         app_event_callback_s event_callback;
1191
1192         event_callback.create = app_create;
1193         event_callback.terminate = app_terminate;
1194         event_callback.pause = app_pause;
1195         event_callback.resume = app_resume;
1196         event_callback.service = app_service;
1197         event_callback.low_memory = NULL;
1198         event_callback.low_battery = low_battery_cb;
1199         event_callback.device_orientation = device_orientation;
1200         event_callback.language_changed = lang_changed;
1201         event_callback.region_format_changed = region_changed_cb;
1202
1203         D_LEAVE;
1204         return app_efl_main(&argc, &argv, &event_callback, &ad);
1205 }