Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / protocol-plugin / sample-app / tizen / PPMSampleApp / src / ppmsampleapp.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "ppmsampleapp.h"
22
23 #include <tizen.h>
24 #include <wifi.h>
25 #include <algorithm>
26 #include "string.h"
27 #include <time.h>
28 #include <pthread.h>
29
30 #include "PluginManager.h"
31 #include "OCPlatform.h"
32 #include "PluginManager.h"
33 #include "OCApi.h"
34
35 using namespace OC;
36 using namespace OIC;
37
38 class Fan
39 {
40     public:
41
42         bool m_state;
43         int m_power;
44         std::string m_name;
45
46         Fan() : m_state(false), m_power(0), m_name("")
47         {
48         }
49 };
50
51 typedef struct appdata
52 {
53     Evas_Object *win;
54     Evas_Object *conform;
55     Evas_Object *naviframe;
56     Evas_Object *box;
57
58     Evas_Object *log;
59
60     Evas_Object *send_msg_button;
61     Evas_Object *clear_log_button;
62 } appdata_s;
63
64 typedef struct threadContext
65 {
66     appdata_s *ad;
67     const char *log;
68 } threadContext_s;
69
70 threadContext_s m_ThreadContext;
71 bool isSendMessage = true;
72 const int SUCCESS_RESPONSE = 0;
73 std::shared_ptr<OCResource> curFanResource;
74 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
75 int count = 0;
76 Fan myfan;
77 char log_buffer[10000];
78 PluginManager *m_pm = NULL;
79 char temp_string[2000];
80 char buf[100];
81
82 void putFanRepresentation(std::shared_ptr<OCResource> resource);
83
84 void updateLog(appdata_s *ad, const char *newlog)
85 {
86     const char *log_text = NULL;
87
88     log_text = elm_entry_entry_get(ad->log);
89     strcpy(log_buffer, log_text);
90     strcat(log_buffer, newlog);
91     elm_entry_entry_set(ad->log, log_buffer);
92     elm_entry_cursor_end_set(ad->log);
93 }
94
95 void *updateCallbackLog(void *data)
96 {
97     threadContext_s  *pThreadContext = (threadContext_s *)data;
98     updateLog(pThreadContext->ad, pThreadContext->log);
99     return NULL;
100 }
101
102
103 int observe_count()
104 {
105     static int oc = 0;
106     return ++oc;
107 }
108
109 void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
110                const int &eCode, const int &sequenceNumber)
111 {
112     if (eCode == OC_STACK_OK)
113     {
114         std::cout << "OBSERVE RESULT:" << std::endl;
115         std::cout << "\tSequenceNumber: " << sequenceNumber << std::endl;
116
117         rep.getValue("state", myfan.m_state);
118         rep.getValue("power", myfan.m_power);
119         rep.getValue("name", myfan.m_name);
120
121         sprintf(buf, "OBSERVE RESULT: sequence number = %d<br>", sequenceNumber);
122         strcpy(temp_string, buf);
123         sprintf(buf, "state: = %d<br>", myfan.m_state);
124         strcat(temp_string, buf);
125         sprintf(buf, "power: = %d<br>", myfan.m_power);
126         strcat(temp_string, buf);
127         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
128         strcat(temp_string, buf);
129         m_ThreadContext.log = temp_string;
130         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
131                                               &m_ThreadContext);
132
133         if (observe_count() > 30)
134         {
135             std::cout << "Cancelling Observe..." << std::endl;
136             OCStackResult result = curFanResource->cancelObserve();
137
138             std::cout << "Cancel result: " << result << std::endl;
139             sleep(10);
140             std::cout << "DONE" << std::endl;
141             std::exit(0);
142         }
143     }
144     else
145     {
146         std::cout << "onObserve Response error: " << eCode << std::endl;
147         sprintf(buf, "onObserve Response error:  = %d<br>", eCode);
148         strcpy(temp_string, buf);
149         m_ThreadContext.log = temp_string;
150         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
151                                               &m_ThreadContext);
152         std::exit(-1);
153     }
154 }
155
156 void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
157 {
158     if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
159     {
160         std::cout << "POST request was successful" << std::endl;
161
162         if (rep.hasAttribute("createduri"))
163         {
164             std::cout << "\tUri of the created resource: "
165                       << rep.getValue<std::string>("createduri") << std::endl;
166         }
167         else
168         {
169             rep.getValue("state", myfan.m_state);
170             rep.getValue("power", myfan.m_power);
171             rep.getValue("name", myfan.m_name);
172
173             std::cout << "\tstate: " << myfan.m_state << std::endl;
174             std::cout << "\tpower: " << myfan.m_power << std::endl;
175             std::cout << "\tname: " << myfan.m_name << std::endl;
176
177             strcpy(temp_string, "POST2 request was successful<br>");
178             sprintf(buf, "state: = %d<br>", myfan.m_state);
179             strcat(temp_string, buf);
180             sprintf(buf, "power: = %d<br>", myfan.m_power);
181             strcat(temp_string, buf);
182             sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
183             strcat(temp_string, buf);
184             m_ThreadContext.log = temp_string;
185             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
186                                                   &m_ThreadContext);
187         }
188
189         if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
190             std::cout << std::endl << "Observe is used." << std::endl;
191         else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
192             std::cout << std::endl << "ObserveAll is used." << std::endl;
193
194         // curFanResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
195
196     }
197     else
198     {
199         std::cout << "onPost Response error: " << eCode << std::endl;
200         sprintf(buf, "onPost Response error:  = %d<br>", eCode);
201         strcpy(temp_string, buf);
202         m_ThreadContext.log = temp_string;
203         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
204                                               &m_ThreadContext);
205         std::exit(-1);
206     }
207 }
208
209 void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
210 {
211     if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
212     {
213         std::cout << "POST request was successful" << std::endl;
214
215         if (rep.hasAttribute("createduri"))
216         {
217             std::cout << "\tUri of the created resource: "
218                       << rep.getValue<std::string>("createduri") << std::endl;
219         }
220         else
221         {
222             rep.getValue("state", myfan.m_state);
223             rep.getValue("power", myfan.m_power);
224             rep.getValue("name", myfan.m_name);
225
226             std::cout << "\tstate: " << myfan.m_state << std::endl;
227             std::cout << "\tpower: " << myfan.m_power << std::endl;
228             std::cout << "\tname: " << myfan.m_name << std::endl;
229
230             strcpy(temp_string, "POST request was successful<br>");
231             sprintf(buf, "state: = %d<br>", myfan.m_state);
232             strcat(temp_string, buf);
233             sprintf(buf, "power: = %d<br>", myfan.m_power);
234             strcat(temp_string, buf);
235             sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
236             strcat(temp_string, buf);
237             m_ThreadContext.log = temp_string;
238             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
239                                                   &m_ThreadContext);
240         }
241
242         OCRepresentation rep2;
243
244         std::cout << "Posting fan representation..." << std::endl;
245
246         myfan.m_state = true;
247         myfan.m_power = 55;
248
249         rep2.setValue("state", myfan.m_state);
250         rep2.setValue("power", myfan.m_power);
251
252         curFanResource->post(rep2, QueryParamsMap(), &onPost2);
253     }
254     else
255     {
256         std::cout << "onPost Response error: " << eCode << std::endl;
257         sprintf(buf, "onPost Response error:  = %d<br>", eCode);
258         strcpy(temp_string, buf);
259         m_ThreadContext.log = temp_string;
260         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
261                                               &m_ThreadContext);
262         std::exit(-1);
263     }
264 }
265
266 // Local function to put a different state for this resource
267 void postFanRepresentation(std::shared_ptr<OCResource> resource)
268 {
269     if (resource)
270     {
271         OCRepresentation rep;
272
273         std::cout << "Posting fan representation..." << std::endl;
274
275         myfan.m_state = false;
276         myfan.m_power = 105;
277
278         rep.setValue("state", myfan.m_state);
279         rep.setValue("power", myfan.m_power);
280
281         // Invoke resource's post API with rep, query map and the callback parameter
282         resource->post(rep, QueryParamsMap(), &onPost);
283     }
284 }
285
286 // Callback handler on PUT request
287 void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
288 {
289     if (eCode == OC_STACK_OK)
290     {
291         std::cout << "PUT request was successful" << std::endl;
292
293         rep.getValue("state", myfan.m_state);
294         rep.getValue("power", myfan.m_power);
295         rep.getValue("name", myfan.m_name);
296
297         std::cout << "\tstate: " << myfan.m_state << std::endl;
298         std::cout << "\tpower: " << myfan.m_power << std::endl;
299         std::cout << "\tname: " << myfan.m_name << std::endl;
300
301         strcpy(temp_string, "PUT request was successful<br>");
302         sprintf(buf, "state: = %d<br>", myfan.m_state);
303         strcat(temp_string, buf);
304         sprintf(buf, "power: = %d<br>", myfan.m_power);
305         strcat(temp_string, buf);
306         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
307         strcat(temp_string, buf);
308         m_ThreadContext.log = temp_string;
309         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
310                                               &m_ThreadContext);
311
312         putFanRepresentation(curFanResource);
313     }
314     else
315     {
316         std::cout << "onPut Response error: " << eCode << std::endl;
317         sprintf(buf, "onPut Response error:  = %d<br>", eCode);
318         strcpy(temp_string, buf);
319         m_ThreadContext.log = temp_string;
320         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
321                                               &m_ThreadContext);
322         std::exit(-1);
323     }
324 }
325
326 // Local function to put a different state for this resource
327 void putFanRepresentation(std::shared_ptr<OCResource> resource)
328 {
329     if (resource)
330     {
331         OCRepresentation rep;
332
333         std::cout << "Putting fan representation..." << std::endl;
334
335         myfan.m_state = true;
336         if (myfan.m_power == 1)
337             myfan.m_power = 0;
338         else
339             myfan.m_power = 1;
340         sleep(5);
341         rep.setValue("state", myfan.m_state);
342         rep.setValue("power", myfan.m_power);
343
344         // Invoke resource's put API with rep, query map and the callback parameter
345         resource->put(rep, QueryParamsMap(), &onPut);
346     }
347 }
348
349 // Callback handler on GET request
350 void onFanGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
351 {
352     if (eCode == OC_STACK_OK)
353     {
354         std::cout << "GET Fan request was successful" << std::endl;
355         std::cout << "Resource URI: " << rep.getUri() << std::endl;
356
357         rep.getValue("state", myfan.m_state);
358         rep.getValue("power", myfan.m_power);
359         rep.getValue("name", myfan.m_name);
360
361         std::cout << "\tstate: " << myfan.m_state << std::endl;
362         std::cout << "\tpower: " << myfan.m_power << std::endl;
363         std::cout << "\tname: " << myfan.m_name << std::endl;
364
365         strcpy(temp_string, "GET Fan request was successful<br>");
366         sprintf(buf, "state: = %d<br>", myfan.m_state);
367         strcat(temp_string, buf);
368         sprintf(buf, "power: = %d<br>", myfan.m_power);
369         strcat(temp_string, buf);
370         sprintf(buf, "name: = %s<br>", myfan.m_name.c_str());
371         strcat(temp_string, buf);
372         m_ThreadContext.log = temp_string;
373         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
374                                               &m_ThreadContext);
375
376         putFanRepresentation(curFanResource);
377     }
378     else
379     {
380         std::cout << "onGET Response error: " << eCode << std::endl;
381         sprintf(buf, "onGET Response error:  = %d<br>", eCode);
382         strcpy(temp_string, buf);
383         m_ThreadContext.log = temp_string;
384         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
385                                               &m_ThreadContext);
386         std::exit(-1);
387     }
388 }
389
390
391 // Local function to get representation of fan resource
392 void getFanRepresentation(std::shared_ptr<OCResource> resource)
393 {
394     if (resource)
395     {
396         std::cout << "Getting Fan Representation..." << std::endl;
397
398         // Invoke resource's get API with the callback parameter
399         QueryParamsMap test;
400         resource->get(test, &onFanGet);
401     }
402 }
403
404 // Callback to found resources
405 void foundResourceFan(std::shared_ptr<OCResource> resource)
406 {
407     if (curFanResource)
408     {
409         std::cout << "Found another resource, ignoring" << std::endl;
410     }
411
412     std::string resourceURI;
413     std::string hostAddress;
414     try
415     {
416         // Do some operations with resource object.
417         if (resource)
418         {
419             std::cout << "DISCOVERED Resource:" << std::endl;
420             strcpy(temp_string, "DISCOVERED Resource:");
421
422             // Get the resource URI
423             resourceURI = resource->uri();
424             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
425             sprintf(buf, "URI of the resource: = %s<br>", resourceURI.c_str());
426             strcat(temp_string, buf);
427
428             // Get the resource host address
429             hostAddress = resource->host();
430             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
431             sprintf(buf, "Host address of the resource: = %s<br>", hostAddress.c_str());
432             strcat(temp_string, buf);
433
434             // Get the resource types
435             std::cout << "\tList of resource types: " << std::endl;
436             strcat(temp_string, "List of resource types: <br>");
437             for (auto & resourceTypes : resource->getResourceTypes())
438             {
439                 std::cout << "\t\t" << resourceTypes << std::endl;
440                 sprintf(buf, "%s<br>", resourceTypes.c_str());
441                 strcat(temp_string, buf);
442             }
443
444             // Get the resource interfaces
445             std::cout << "\tList of resource interfaces: " << std::endl;
446             for (auto & resourceInterfaces : resource->getResourceInterfaces())
447             {
448                 std::cout << "\t\t" << resourceInterfaces << std::endl;
449                 sprintf(buf, "%s<br>", resourceInterfaces.c_str());
450                 strcat(temp_string, buf);
451             }
452
453             if (resourceURI == "/a/fan")
454             {
455                 curFanResource = resource;
456                 /* Call a local function which will internally invoke get API
457                    on the resource pointer */
458                 putFanRepresentation(curFanResource);
459             }
460             m_ThreadContext.log = temp_string;
461             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
462                                                   &m_ThreadContext);
463         }
464         else
465         {
466             // Resource is invalid
467             std::cout << "Resource is invalid" << std::endl;
468             strcpy(temp_string, "Resource is invalid");
469             m_ThreadContext.log = temp_string;
470             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
471                                                   &m_ThreadContext);
472         }
473
474     }
475     catch (std::exception &e)
476     {
477         // log(e.what());
478     }
479 }
480
481 void PrintUsage()
482 {
483     std::cout << std::endl;
484     std::cout << "Usage : simpleclient <ObserveType>" << std::endl;
485     std::cout << "   ObserveType : 1 - Observe" << std::endl;
486     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
487 }
488
489 static void
490 win_delete_request_cb(void *data , Evas_Object *obj , void *event_info)
491 {
492     ui_app_exit();
493 }
494
495 static void
496 win_back_cb(void *data, Evas_Object *obj, void *event_info)
497 {
498     ui_app_exit();
499 }
500
501 static void
502 send_msg_clicked_cb(void *data , Evas_Object *obj , void *event_info)
503 {
504     appdata_s *ad = (appdata_s *)data;
505     if (isSendMessage == true)
506     {
507         try
508         {
509             m_pm = new PluginManager();
510
511             // Get Plugins
512             std::vector<Plugin> user_plugin;
513
514             user_plugin = m_pm->getPlugins();
515
516             for (unsigned int i = 0; i < user_plugin.size(); i++)
517             {
518                 strcpy(temp_string, "Calling Get Plugin<br>");
519                 sprintf(buf, "value Name = %s<br>", user_plugin[i].getName().c_str());
520                 strcat(temp_string, buf);
521                 sprintf(buf, "value ID = %s<br>", user_plugin[i].getID().c_str());
522                 strcat(temp_string, buf);
523                 m_ThreadContext.log = temp_string;
524                 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
525                                                       &m_ThreadContext);
526                 std::cout << "value Name = " << user_plugin[i].getName() << std::endl;
527                 std::cout << "value ID = " << user_plugin[i].getID() << std::endl;
528             }
529
530
531             std::cout << "start fan Plugin by Resource Type"  << std::endl;
532             strcpy(temp_string, "start fan Plugin<br>");
533             strcat(temp_string, "fan Plugin is getting started. Please wait...<br>");
534             m_ThreadContext.log = temp_string;
535             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateCallbackLog,
536                                                   &m_ThreadContext);
537             m_pm->startPlugins("ResourceType", "oic.fan");
538             sleep(2);
539             // Makes it so that all boolean values are printed as 'true/false' in this stream
540             std::cout.setf(std::ios::boolalpha);
541             std::cout << "Before find Resource... " << std::endl;
542
543             // Find fan resources
544             std::ostringstream requestURI;
545             requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.fan";
546             OCPlatform::findResource("", requestURI.str(), OC_ALL, &foundResourceFan);
547             std::cout << "Finding Resource... " << std::endl;
548         }
549         catch (OCException &e)
550         {
551             // log(e.what());
552         }
553
554         elm_object_text_set(ad->send_msg_button, "Press here to close the App");
555         isSendMessage = false;
556     }
557     else
558     {
559         isSendMessage = true;
560         ui_app_exit();
561     }
562 }
563
564 static void
565 clear_log_clicked_cb(void *data , Evas_Object *obj , void *event_info)
566 {
567     appdata_s *ad = (appdata_s *)data;
568     elm_entry_entry_set(ad->log, "");
569 }
570
571 static void
572 create_base_gui(appdata_s *ad)
573 {
574     // Window
575     ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
576     elm_win_autodel_set(ad->win, EINA_TRUE);
577
578     if (elm_win_wm_rotation_supported_get(ad->win))
579     {
580         int rots[4] = { 0, 90, 180, 270 };
581         elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
582     }
583
584     evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
585     eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
586
587     // Conformant
588     ad->conform = elm_conformant_add(ad->win);
589     elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
590     elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
591     evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
592     elm_win_resize_object_add(ad->win, ad->conform);
593     evas_object_show(ad->conform);
594
595     // naviframe
596     ad->naviframe = elm_naviframe_add(ad->conform);
597     elm_object_content_set(ad->conform, ad->naviframe);
598     evas_object_show(ad->naviframe);
599
600     // Box container
601     ad->box = elm_box_add(ad->naviframe);
602     elm_box_horizontal_set(ad->box, EINA_FALSE);
603     evas_object_size_hint_weight_set(ad->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
604     evas_object_size_hint_align_set(ad->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
605     elm_box_padding_set(ad->box, 0, 15 * elm_config_scale_get());
606     elm_naviframe_item_push(ad->naviframe, "ProtocolPlugin App", NULL, NULL, ad->box, NULL);
607     evas_object_show(ad->box);
608
609     ad->send_msg_button = elm_button_add(ad->box);
610     evas_object_size_hint_align_set(ad->send_msg_button, EVAS_HINT_FILL, 0.0);
611     elm_object_text_set(ad->send_msg_button, "Invoke Fan Plugin");
612     evas_object_smart_callback_add(ad->send_msg_button, "clicked", send_msg_clicked_cb, ad);
613     elm_box_pack_end(ad->box, ad->send_msg_button);
614     evas_object_show(ad->send_msg_button);
615
616     ad->clear_log_button = elm_button_add(ad->box);
617     evas_object_size_hint_align_set(ad->clear_log_button, EVAS_HINT_FILL, 0.0);
618     elm_object_text_set(ad->clear_log_button, "Clear Log");
619     evas_object_smart_callback_add(ad->clear_log_button, "clicked", clear_log_clicked_cb, ad);
620     elm_box_pack_end(ad->box, ad->clear_log_button);
621     evas_object_show(ad->clear_log_button);
622
623     ad->log = elm_entry_add(ad->box);
624     elm_object_part_text_set(ad->log, "elm.guide", "Log messages will be update here!!!");
625     elm_entry_scrollable_set(ad->log, EINA_TRUE);
626     evas_object_size_hint_weight_set(ad->log, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
627     evas_object_size_hint_align_set(ad->log, EVAS_HINT_FILL, EVAS_HINT_FILL);
628     elm_box_pack_end(ad->box, ad->log);
629     evas_object_show(ad->log);
630
631     // Show window after base gui is set up
632     evas_object_show(ad->win);
633
634     std::string name;
635     std::string key = "Name";
636     std::string  state = "";
637     std::string  id = "";
638
639     // Create PlatformConfig object
640     PlatformConfig cfg
641     {
642         OC::ServiceType::InProc,
643         OC::ModeType::Both,
644         "0.0.0.0",
645         0,
646         OC::QualityOfService::LowQos
647     };
648
649     OCPlatform::Configure(cfg);
650 }
651
652 static bool
653 app_create(void *data)
654 {
655     /* Hook to take necessary actions before main event loop starts
656         Initialize UI resources and application's data
657         If this function returns true, the main loop of application starts
658         If this function returns false, the application is terminated */
659     appdata_s *ad = (appdata_s *)data;
660     m_ThreadContext.ad = ad;
661     m_ThreadContext.log = NULL;
662     create_base_gui(ad);
663
664     return true;
665 }
666
667 static void
668 app_control(app_control_h app_control, void *data)
669 {
670     // Handle the launch request.
671     dlog_print(DLOG_INFO, LOG_TAG, "#### in app_control");
672 }
673
674 static void
675 app_pause(void *data)
676 {
677     // Take necessary actions when application becomes invisible.
678     dlog_print(DLOG_INFO, LOG_TAG, "#### in app_pause");
679 }
680
681 static void
682 app_resume(void *data)
683 {
684     // Take necessary actions when application becomes visible.
685     dlog_print(DLOG_INFO, LOG_TAG, "#### in app_resume");
686 }
687
688 static void
689 app_terminate(void *data)
690 {
691     // Release all resources.
692     dlog_print(DLOG_INFO, LOG_TAG, "#### in app_terminate");
693
694 }
695
696 static void
697 ui_app_lang_changed(app_event_info_h event_info, void *user_data)
698 {
699     // APP_EVENT_LANGUAGE_CHANGED
700     char *locale = NULL;
701     system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
702     elm_language_set(locale);
703     free(locale);
704     return;
705 }
706
707 static void
708 ui_app_orient_changed(app_event_info_h event_info, void *user_data)
709 {
710     // APP_EVENT_DEVICE_ORIENTATION_CHANGED
711     dlog_print(DLOG_INFO, LOG_TAG, "#### app orient changed");
712     return;
713 }
714
715 static void
716 ui_app_region_changed(app_event_info_h event_info, void *user_data)
717 {
718     // APP_EVENT_REGION_FORMAT_CHANGED
719 }
720
721 static void
722 ui_app_low_battery(app_event_info_h event_info, void *user_data)
723 {
724     // APP_EVENT_LOW_BATTERY
725 }
726
727 static void
728 ui_app_low_memory(app_event_info_h event_info, void *user_data)
729 {
730     // APP_EVENT_LOW_MEMORY
731 }
732
733 int
734 main(int argc, char *argv[])
735 {
736     appdata_s ad = {0,};
737     int ret = 0;
738
739     ui_app_lifecycle_callback_s event_callback = {0,};
740     app_event_handler_h handlers[5] = {NULL, };
741
742     event_callback.create = app_create;
743     event_callback.terminate = app_terminate;
744     event_callback.pause = app_pause;
745     event_callback.resume = app_resume;
746     event_callback.app_control = app_control;
747
748     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY,
749                              ui_app_low_battery, &ad);
750     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY,
751                              ui_app_low_memory, &ad);
752     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED],
753                              APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
754     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED,
755                              ui_app_lang_changed, &ad);
756     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
757                              APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
758     ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
759
760     ret = ui_app_main(argc, argv, &event_callback, &ad);
761
762     if (ret != APP_ERROR_NONE)
763     {
764         dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
765     }
766
767     return ret;
768 }