Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / tizen / RESampleClientApp / src / reclient.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 "reclient.h"
22
23 #include<iostream>
24
25 #include "reclientmain.h"
26
27 #include "RCSDiscoveryManager.h"
28 #include "RCSRemoteResourceObject.h"
29 #include "RCSResourceAttributes.h"
30 #include "RCSAddress.h"
31
32 #include "OCPlatform.h"
33
34 # define checkResource nullptr == resource?false:true
35
36 using namespace std;
37 using namespace OC;
38 using namespace OIC::Service;
39
40 constexpr int CORRECT_INPUT = 1;
41 constexpr int INCORRECT_INPUT = 2;
42 constexpr int QUIT_INPUT = 3;
43
44 std::shared_ptr<RCSRemoteResourceObject>  resource;
45 std::vector<RCSRemoteResourceObject::Ptr> resourceList;
46 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
47
48 const std::string defaultKey = "Temperature";
49 const std::string resourceType = "oic.r.temperaturesensor";
50
51 static Evas_Object *log_entry = NULL;
52 static Evas_Object *list = NULL;
53 static Evas_Object *naviframe = NULL;
54
55 typedef struct temperature_popup
56 {
57     Evas_Object *popup;
58     Evas_Object *entry;
59 } temperature_popup_fields;
60
61 // Function to update the log in UI
62 void *updateGroupLog(void *data)
63 {
64     string *log = (string *)data;
65     // Show the log
66     elm_entry_entry_append(log_entry, (*log).c_str());
67     elm_entry_cursor_end_set(log_entry);
68     return NULL;
69 }
70
71 static void onDestroy()
72 {
73     dlog_print(DLOG_INFO, LOG_TAG, "#### Destroy sequence called");
74     resourceList.clear();
75     resource = nullptr;
76 }
77
78 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
79 {
80     dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceDiscovered callback");
81
82     std::string resourceURI = foundResource->getUri();
83     std::string hostAddress = foundResource->getAddress();
84
85     int resourceSize = resourceList.size() + 1;
86     string logMessage = "Resource Found : " + std::to_string(resourceSize) + "<br>";
87     logMessage = logMessage + "URI: " + resourceURI + "<br>";
88     logMessage = logMessage + "Host:" + hostAddress + "<br>";
89     logMessage += "----------------------<br>";
90     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
91     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
92                                           &logMessage);
93
94     resourceList.push_back(foundResource);
95
96     if ("/a/TempSensor" == resourceURI)
97         resource = foundResource;
98 }
99
100 void onResourceStateChanged(const ResourceState &resourceState)
101 {
102     dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceStateChanged");
103
104     std::string logMessage = "State changed to : ";
105
106     switch (resourceState)
107     {
108         case ResourceState::NONE:
109             logMessage = logMessage + "NOT_MONITORING <br>";
110             break;
111
112         case ResourceState::ALIVE:
113             logMessage = logMessage + "ALIVE <br>";
114             break;
115
116         case ResourceState::REQUESTED:
117             logMessage = logMessage + "REQUESTED <br>";
118             break;
119
120         case ResourceState::LOST_SIGNAL:
121             logMessage = logMessage + "LOST_SIGNAL <br>";
122             resource = nullptr;
123             break;
124
125         case ResourceState::DESTROYED:
126             logMessage = logMessage + "DESTROYED <br>";
127             break;
128     }
129
130     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
131     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
132                                           &logMessage);
133 }
134
135 void onCacheUpdated(const RCSResourceAttributes &attributes)
136 {
137     dlog_print(DLOG_INFO, LOG_TAG, "#### onCacheUpdated callback");
138
139     string logMessage = "Cache Updated : <br> ";
140
141     if (attributes.empty())
142     {
143         logMessage + logMessage + "Attribute is Empty <br>";
144         return;
145     }
146
147     for (const auto & attr : attributes)
148     {
149         logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
150         logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
151     }
152     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
153     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
154                                           &logMessage);
155 }
156
157 void onRemoteAttributesReceived(const RCSResourceAttributes &attributes, int)
158 {
159     dlog_print(DLOG_INFO, LOG_TAG, "#### onRemoteAttributesReceived entry");
160
161     string logMessage = "Remote Attribute Updated : <br> ";
162
163     if (attributes.empty())
164     {
165         logMessage + logMessage + "Attribute is Empty <br>";
166         return;
167     }
168
169     for (const auto & attr : attributes)
170     {
171         logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
172         logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
173     }
174
175     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
176     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
177                                           &logMessage);
178 }
179
180 static void startMonitoring(void *data, Evas_Object *obj, void *event_info)
181 {
182     string logMessage = "";
183
184     if (checkResource)
185     {
186         if (!resource->isMonitoring())
187         {
188             try
189             {
190                 logMessage = logMessage + "Started Monitoring <br>";
191                 resource->startMonitoring(&onResourceStateChanged);
192             }
193             catch (const RCSBadRequestException &e)
194             {
195                 logMessage = logMessage + "Exception BadRequest<br>";
196                 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
197             }
198             catch (const RCSInvalidParameterException &e)
199             {
200                 logMessage = logMessage + "Exception Invalid Param<br>";
201                 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
202             }
203         }
204         else
205         {
206             logMessage = logMessage + "Already Monitoring <br>";
207         }
208     }
209     else
210     {
211         logMessage = logMessage + "No Resource to monitor <br>";
212     }
213
214     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
215     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
216                                           &logMessage);
217 }
218
219 static void stopMonitoring(void *data, Evas_Object *obj, void *event_info)
220 {
221     string logMessage = "";
222
223     if (checkResource)
224     {
225         if (resource->isMonitoring())
226         {
227             resource->stopMonitoring();
228             logMessage = logMessage + "Stopped Monitoring <br>";
229         }
230         else
231         {
232             logMessage = logMessage + "Monitoring not started <br>";
233         }
234     }
235     else
236     {
237         logMessage = logMessage + "NO Resource to stop monitor <br>";
238     }
239
240     dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
241     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
242                                           &logMessage);
243 }
244
245 static void list_selected_cb(void *data, Evas_Object *obj, void *event_info)
246 {
247     Elm_Object_Item *it = (Elm_Object_Item *)event_info;
248     elm_list_item_selected_set(it, EINA_FALSE);
249 }
250
251 static void getAttributeFromRemoteServer(void *data, Evas_Object *obj, void *event_info)
252 {
253     if (checkResource)
254     {
255         resource->getRemoteAttributes(&onRemoteAttributesReceived);
256     }
257     else
258     {
259         dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getAttributeFromRemoteServer...");
260     }
261 }
262
263 static void setAttributeToRemoteServer(int setTemperature)
264 {
265     string key = "Temperature";
266     string logMessage = "";
267
268     RCSResourceAttributes setAttribute;
269     setAttribute[key] = setTemperature;
270
271     if (checkResource)
272     {
273         resource->setRemoteAttributes(setAttribute,
274                                       &onRemoteAttributesReceived);
275     }
276     else
277     {
278         logMessage = "No Resource to setAttributeToRemoteServer";
279     }
280
281     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
282     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
283                                           &logMessage);
284 }
285
286 static void startCaching(std::function <void (const RCSResourceAttributes &)>cb)
287 {
288     string logMessage = "";
289
290     if (checkResource)
291     {
292         if (!resource->isCaching())
293         {
294             if (cb)
295             {
296                 try
297                 {
298                     logMessage = logMessage + "Caching with callback <br>";
299                     resource->startCaching(&onCacheUpdated);
300                 }
301                 catch (const RCSBadRequestException &e)
302                 {
303                     logMessage = logMessage + "Exception BadRequest<br>";
304                     dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
305                 }
306
307             }
308             else
309             {
310                 try
311                 {
312                     logMessage = logMessage + "Caching without callback <br>";
313                     resource->startCaching();
314                 }
315                 catch (const RCSBadRequestException &e)
316                 {
317                     logMessage = logMessage + "Exception BadRequest<br>";
318                     dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
319                 }
320             }
321         }
322         else
323         {
324             logMessage = logMessage + "Caching Already Started <br>";
325         }
326     }
327     else
328     {
329         logMessage = logMessage + "No resource to start Caching <br>";
330     }
331
332     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
333     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
334                                           &logMessage);
335 }
336
337 static void startCachingWithoutCallback(void *data, Evas_Object *obj, void *event_info)
338 {
339     startCaching(nullptr);
340 }
341
342 static void startCachingWithCallback(void *data, Evas_Object *obj, void *event_info)
343 {
344     startCaching(onCacheUpdated);
345 }
346
347 static void getResourceCacheState(void *data, Evas_Object *obj, void *event_info)
348 {
349     string logMessage = "CACHE STATE : ";
350     switch (resource->getCacheState())
351     {
352         case CacheState::READY:
353             logMessage = logMessage + "READY <br>";
354             break;
355
356         case CacheState::UNREADY:
357             logMessage = logMessage + "UNREADY <br>";
358             break;
359
360         case CacheState::LOST_SIGNAL:
361             logMessage = logMessage + "LOST_SIGNAL <br>";
362             break;
363
364         case CacheState::NONE:
365             logMessage = logMessage + "NONE <br>";
366             break;
367
368         default:
369             break;
370     }
371
372     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
373     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
374                                           &logMessage);
375 }
376
377 static void getCachedAttributes(void *data, Evas_Object *obj, void *event_info)
378 {
379     string logMessage = "";
380
381     if (checkResource)
382     {
383         try
384         {
385             if (resource->getCachedAttributes().empty())
386             {
387                 logMessage = "Cached attribute empty<br>";
388             }
389             else
390             {
391                 for (const auto & attr : resource->getCachedAttributes())
392                 {
393                     logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
394                     logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
395                     dlog_print(DLOG_INFO, LOG_TAG, "#### Cached attributes received ");
396                 }
397             }
398         }
399         catch (const RCSBadRequestException &e)
400         {
401             logMessage = "Exception Received<br>";
402             dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttributes : %s", e.what());
403         }
404     }
405     else
406     {
407         logMessage = logMessage + "No Resource<br>";
408         dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getCachedAttributes...");
409     }
410
411     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
412     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
413                                           &logMessage);
414 }
415
416 static void getCachedAttribute(void *data, Evas_Object *obj, void *event_info)
417 {
418     string logMessage = "";
419
420     if (checkResource)
421     {
422         try
423         {
424             logMessage = logMessage + "KEY:" + defaultKey.c_str() + "<br>";
425             int attrValue = resource->getCachedAttribute(defaultKey).get< int >();
426             logMessage = logMessage + "VALUE:" + to_string(attrValue) + "<br>";
427         }
428         catch (const RCSBadRequestException &e)
429         {
430             logMessage = logMessage + "Exception BadRequest<br>";
431             dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
432         }
433         catch (const RCSBadGetException &e)
434         {
435             logMessage = logMessage + "Exception BadGet<br>";
436             dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
437         }
438     }
439     else
440     {
441         logMessage = logMessage + "No resource<br>";
442     }
443
444     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
445     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
446                                           &logMessage);
447 }
448
449 static void stopCaching(void *data, Evas_Object *obj, void *event_info)
450 {
451     string logMessage = "";
452
453     if (checkResource)
454     {
455         if (resource->isCaching())
456         {
457             resource->stopCaching();
458             logMessage = logMessage + "Caching stopped <br>";
459         }
460         else
461         {
462             logMessage = logMessage + "Caching not started <br>";
463         }
464     }
465     else
466     {
467         logMessage = logMessage + "No resource found<br>";
468     }
469
470     dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
471     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
472                                           &logMessage);
473 }
474
475 void discoverResource()
476 {
477     dlog_print(DLOG_INFO, LOG_TAG, "#### discovery started");
478
479     while (!discoveryTask)
480     {
481         try
482         {
483             discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
484                                 RCSAddress::multicast(), resourceType, &onResourceDiscovered);
485         }
486         catch (const RCSPlatformException &e)
487         {
488             std::cout << e.what() << std::endl;
489         }
490     }
491
492     dlog_print(DLOG_INFO, LOG_TAG, "#### Discovery over");
493 }
494
495 void cancelDiscoverResource()
496 {
497     dlog_print(DLOG_INFO, LOG_TAG, "#### cancelDiscoverResource entry");
498     string logMessage = "";
499
500     if (!discoveryTask)
501     {
502         logMessage += "There is no discovery request <br>";
503     }
504     else
505     {
506         discoveryTask->cancel();
507
508         logMessage += "Discovery canceled <br>";
509
510         int resourceSize = resourceList.size();
511         if (!resourceSize)
512         {
513             logMessage += "No Resource Discovered <br>";
514         }
515         else
516         {
517             logMessage += std::to_string(resourceSize) + " : Resource Discovered <br>";
518             ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showClientAPIs, NULL);
519         }
520
521     }
522
523     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
524     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
525                                           &logMessage);
526 }
527
528 static void
529 popup_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
530 {
531     temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
532     evas_object_del(popup_fields->popup);
533     free(popup_fields);
534 }
535
536 static void
537 popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
538 {
539     temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
540     Evas_Object *entry = popup_fields->entry;
541     const char *temperatureString = elm_entry_entry_get(entry);
542     // Remove white spaces(if any) at the beginning
543     int beginning = 0;
544     while (temperatureString[beginning] == ' ')
545     {
546         (beginning)++;
547     }
548
549     int len = strlen(temperatureString);
550     if (NULL == temperatureString || 1 > len)
551     {
552         dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL Temperature Value");
553         string logMessage = "Temperature Cannot be NULL<br>";
554         logMessage += "----------------------<br>";
555         dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
556         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
557     }
558     else
559     {
560         int temperate = atoi(temperatureString);
561         string tempString(temperatureString);
562         setAttributeToRemoteServer(temperate);
563         dlog_print(DLOG_INFO, LOG_TAG, "#### Temperature to set : %d", temperate);
564
565         string logMessage = "Temperature to set : " + tempString + "<br>";
566         logMessage += "----------------------<br>";
567         dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
568         ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
569                                               &logMessage);
570     }
571     evas_object_del(popup_fields->popup);
572     free(popup_fields);
573 }
574
575 static void
576 list_scheduled_actionset_cb(void *data, Evas_Object *obj, void *event_info)
577 {
578     Evas_Object *popup, *btn;
579     Evas_Object *nf = naviframe;
580     Evas_Object *entry;
581     Evas_Object *layout;
582
583     /* popup */
584     popup = elm_popup_add(nf);
585     elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
586     eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
587     evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
588     elm_object_part_text_set(popup, "title,text", "Enter the temperature");
589
590     layout = elm_layout_add(popup);
591     elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_datetime_text");
592     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
593     elm_object_content_set(popup, layout);
594
595     entry = elm_entry_add(layout);
596     elm_entry_single_line_set(entry, EINA_TRUE);
597     elm_entry_scrollable_set(entry, EINA_TRUE);
598     evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
599     evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
600     eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
601     elm_object_part_text_set(entry, "elm.guide", "in degree celsius");
602     elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
603     elm_object_part_content_set(layout, "elm.swallow.content", entry);
604
605     temperature_popup_fields *popup_fields;
606     popup_fields = (temperature_popup_fields *)malloc(sizeof(temperature_popup_fields));
607     if (NULL == popup_fields)
608     {
609         dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
610     }
611     else
612     {
613         popup_fields->popup = popup;
614         popup_fields->entry = entry;
615     }
616
617     /* Cancel button */
618     btn = elm_button_add(popup);
619     elm_object_style_set(btn, "popup");
620     elm_object_text_set(btn, "Cancel");
621     elm_object_part_content_set(popup, "button1", btn);
622     evas_object_smart_callback_add(btn, "clicked", popup_cancel_clicked_cb, popup_fields);
623
624     /* Set button */
625     btn = elm_button_add(popup);
626     elm_object_style_set(btn, "popup");
627     elm_object_text_set(btn, "Set");
628     elm_object_part_content_set(popup, "button2", btn);
629     evas_object_smart_callback_add(btn, "clicked", popup_set_clicked_cb, popup_fields);
630
631     evas_object_show(popup);
632 }
633
634 // Method to be called when the Start Discovery UI Button is selected
635 static void
636 find_resource_cb(void *data, Evas_Object *obj, void *event_info)
637 {
638     if (NULL != list)
639     {
640         discoverResource();
641     }
642     else
643     {
644         dlog_print(DLOG_ERROR, "find_resource_cb", "list is NULL - So unable to add items!!!");
645     }
646 }
647
648 // Method to be called when the Cancel Discovery UI Button is selected
649 static void
650 cancel_resource_cb(void *data, Evas_Object *obj, void *event_info)
651 {
652     if (NULL != list)
653     {
654         cancelDiscoverResource();
655     }
656     else
657     {
658         dlog_print(DLOG_ERROR, "cancel_resource_cb", "list is NULL - So unable to add items!!!");
659     }
660 }
661
662 void *showClientAPIs(void *data)
663 {
664     // Add items to the list only if the list is empty
665     const Eina_List *eina_list = elm_list_items_get(list);
666     int count = eina_list_count(eina_list);
667     if (!count)
668     {
669         elm_list_item_append(list, "1. Start Monitoring", NULL, NULL,
670                              startMonitoring, NULL);
671
672         elm_list_item_append(list, "2. Stop Monitoring", NULL, NULL,
673                              stopMonitoring, NULL);
674
675         elm_list_item_append(list, "3. Get Attribute", NULL, NULL,
676                              getAttributeFromRemoteServer, NULL);
677
678         elm_list_item_append(list, "4. Set Attribute", NULL, NULL,
679                              list_scheduled_actionset_cb, NULL);
680
681         elm_list_item_append(list, "5. Start Caching - No update", NULL, NULL,
682                              startCachingWithoutCallback, NULL);
683
684         elm_list_item_append(list, "6. Start Caching - With update", NULL, NULL,
685                              startCachingWithCallback, NULL);
686
687         elm_list_item_append(list, "7. Get Cache State", NULL, NULL,
688                              getResourceCacheState, NULL);
689
690         elm_list_item_append(list, "8. Get cached attributes", NULL, NULL,
691                              getCachedAttributes, NULL);
692
693         elm_list_item_append(list, "9. Stop Caching", NULL, NULL,
694                              stopCaching, NULL);
695
696         elm_list_go(list);
697     }
698     return NULL;
699 }
700
701 static Eina_Bool
702 naviframe_pop_cb(void *data, Elm_Object_Item *it)
703 {
704     onDestroy();
705
706     if (NULL != log_entry)
707     {
708         evas_object_del(log_entry);
709         log_entry = NULL;
710     }
711     if (NULL != list)
712     {
713         evas_object_del(list);
714         list = NULL;
715     }
716     return EINA_TRUE;
717 }
718
719 // Method to be called when the Group APIs UI Button is selected
720 void client_cb(void *data, Evas_Object *obj, void *event_info)
721 {
722     Evas_Object *layout;
723     Evas_Object *scroller;
724     Evas_Object *nf = (Evas_Object *)data;
725     Evas_Object *button1;
726     Evas_Object *button2;
727     Elm_Object_Item *nf_it;
728
729     naviframe = nf;
730
731     // Scroller
732     scroller = elm_scroller_add(nf);
733     elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
734     elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
735
736     // Layout
737     layout = elm_layout_add(nf);
738     elm_layout_file_set(layout, ELM_DEMO_EDJ, "group_layout");
739     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
740
741     elm_object_content_set(scroller, layout);
742
743     // Start Discovery Button
744     button1 = elm_button_add(layout);
745     elm_object_part_content_set(layout, "button1", button1);
746     elm_object_text_set(button1, "Start Discovery");
747     evas_object_smart_callback_add(button1, "clicked", find_resource_cb, NULL);
748
749     // Cancel Discovery Button
750     button2 = elm_button_add(layout);
751     elm_object_part_content_set(layout, "button2", button2);
752     elm_object_text_set(button2, "Cancel Discovery");
753     evas_object_smart_callback_add(button2, "clicked", cancel_resource_cb, NULL);
754
755     // List
756     list = elm_list_add(layout);
757     elm_list_mode_set(list, ELM_LIST_COMPRESS);
758     evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
759     elm_object_part_content_set(layout, "list", list);
760     elm_list_go(list);
761
762     // log_entry - textarea for log
763     log_entry = elm_entry_add(layout);
764     elm_entry_scrollable_set(log_entry, EINA_TRUE);
765     elm_entry_editable_set(log_entry, EINA_FALSE);
766     elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
767     evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
768     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
769     elm_object_part_content_set(layout, "log", log_entry);
770
771     nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", NULL, NULL, scroller, NULL);
772     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);
773 }