[Release] wrt-plugins-common_0.3.66
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / ace / popup-bin / Popup.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        Popup.c
18  * @author      Janusz Kozerski (j.kozerski@samsung.com)
19  * @version     1.0
20  */
21
22 /*
23  * This is just a example pop-up that shows how to use a new C-API in wrt-security.
24  * This pop-up should be re-implemented by members of NGWAP.
25  */
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <vector>
32 #include <ctime>
33
34 #include <Elementary.h>
35
36 #include <dpl/log/log.h>
37 #include <dpl/serialization.h>
38 #include <ace_api_common.h>
39 #include <ace_api_popup_validation.h>
40
41 #include "popup-runner.h"
42 #include "Popup.h"
43
44 namespace { // anonymous
45
46 static void set_validity_from_checkbox(struct ace_popup_data *pdp) {
47
48     if(NULL == pdp){
49         LogError("pdp is NULL; return");
50         return;
51     }
52
53     if (pdp->always) {
54         LogDebug("Remember ALWAYS");
55         pdp->remember_choice = ACE_ALWAYS;
56         return;
57     }
58     if (pdp->per_session) {
59         LogDebug("Remember PER_SESSION");
60         pdp->remember_choice = ACE_PER_SESSION;
61         return;
62     }
63     LogDebug("Remember ONCE");
64     pdp->remember_choice = ACE_ONCE;
65     return;
66 }
67
68 static void on_done(void) {
69     // Quit the efl-mainloop
70     LogDebug("elm_exit()");
71     elm_exit();
72 }
73
74 static void grant_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
75
76     LogDebug("grant_answer");
77     if(NULL == data){
78         LogError("data is NULL; return");
79         return;
80     }
81     struct ace_popup_data *pdp = static_cast <struct ace_popup_data *> (data);
82
83     set_validity_from_checkbox(pdp);
84
85     ace_popup_validation_initialize();
86     pdp->validation_return = ace_validate_answer(
87             ACE_TRUE,
88             pdp->remember_choice,
89             pdp->resource_name,
90             pdp->session_id,
91             &(pdp->param_list),
92             pdp->handle,
93             &(pdp->validation_result));
94     ace_popup_validation_shutdown();
95
96     on_done();
97 }
98
99 static void deny_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
100
101     LogDebug("deny_answer");
102     if(NULL == data){
103         LogError("data is NULL; return");
104         return;
105     }
106     struct ace_popup_data *pdp = static_cast <struct ace_popup_data *> (data);
107
108     set_validity_from_checkbox(pdp);
109
110     ace_popup_validation_initialize();
111     pdp->validation_return = ace_validate_answer(
112             ACE_FALSE,
113             pdp->remember_choice,
114             pdp->resource_name,
115             pdp->session_id,
116             &(pdp->param_list),
117             pdp->handle,
118             &(pdp->validation_result));
119     ace_popup_validation_shutdown();
120
121     on_done();
122 }
123
124 static int _ace_params_deserializer(ace_param_list_t* ace_param_list, Wrt::Popup::BinaryStream *stream){
125
126     LogDebug("_ace_params_deserializer");
127
128     if(NULL == ace_param_list || NULL == stream){
129         LogError("ace_param_list or stream is NULL; return -1");
130         return -1;
131     }
132
133     // deserialize ace_param_list->count;
134     size_t count = 0;
135     DPL::Deserialization::Deserialize(*stream, count);
136     ace_param_list->count = count;
137     LogDebug("count : " << count);
138
139     std::string name;
140     std::string value;
141     if(count == 0){
142         ace_param_list->items = NULL;
143         return 0;
144     }
145     ace_param_list->items = static_cast <ace_param_t *> (malloc(count * sizeof(ace_param_t)));
146     memset(ace_param_list->items, 0, count * sizeof(ace_param_t));
147
148     for(size_t i=0; i < count; ++i){
149         DPL::Deserialization::Deserialize(*stream, name);
150         ace_param_list->items[i].name =
151                 strdup(const_cast <char *> (name.c_str()));
152
153         DPL::Deserialization::Deserialize(*stream, value);
154         ace_param_list->items[i].value =
155                 strdup(const_cast <char *> (value.c_str()));
156     }
157     return 0;
158 }
159
160 static void _ace_params_finalize(ace_param_list_t* ace_param_list) {
161     if (NULL == ace_param_list || ace_param_list->items) {
162         LogDebug("List is null, nothing to do");
163         return;
164     }
165     for (size_t i = 0; i < ace_param_list->count; ++i) {
166         free(ace_param_list->items[i].name);
167         free(ace_param_list->items[i].value);
168     }
169     free(ace_param_list->items);
170     ace_param_list->items = NULL;
171     ace_param_list->count = 0;
172 }
173
174 static void show_popup(struct ace_popup_data *pdp) {
175     LogDebug("show_popup()");
176
177     if(NULL == pdp){
178         LogError("pdp is NULL; return");
179         return;
180     }
181
182     const char *resource_type = static_cast <char *> (pdp->resource_name);
183
184     Evas_Object *win          = NULL;
185     Evas_Object *cb_session   = NULL;
186     Evas_Object *cb_always    = NULL;
187     Evas_Object *box          = NULL;
188     Evas_Object *label        = NULL;
189     Evas_Object *grant_button = NULL;
190     Evas_Object *deny_button  = NULL;
191     pdp->per_session          = EINA_FALSE;
192     pdp->always               = EINA_FALSE;
193
194     win = elm_win_add(NULL, "The wrt-client popup", ELM_WIN_NOTIFICATION);
195     elm_win_autodel_set(win, EINA_TRUE);
196     elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
197     evas_object_show(win);
198     elm_win_indicator_opacity_set(win, ELM_WIN_INDICATOR_TRANSLUCENT);
199
200     pdp->popup = elm_popup_add(win);
201
202     box = elm_box_add(pdp->popup);
203     evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0);
204     evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0.0);
205
206     label = elm_label_add(pdp->popup);
207     elm_object_style_set(label, "popup_description/default");
208     elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
209     char *buff = NULL;
210     if(-1 == asprintf(&buff, "Application need an access to %s.<br>Grant or deny?", resource_type)){
211         LogError("asprintf failed - returned -1");
212         evas_object_del(label);
213         evas_object_del(pdp->popup);
214         evas_object_del(win);
215         return;
216     }
217     elm_object_text_set(label, buff);
218     free(buff);
219     evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
220     evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
221     evas_object_show(label);
222     elm_box_pack_end(box, label);
223
224     LogDebug("popup_type == " << pdp->popup_type);
225     if (pdp->popup_type == ACE_SESSION || pdp->popup_type == ACE_BLANKET) {
226         LogDebug("popup_type == ACE_SESSION || ACE_BLANKET");
227         cb_session = elm_check_add(pdp->popup);
228         elm_object_text_set(cb_session, "Remember choice for this session");
229         elm_check_state_pointer_set(cb_session, &(pdp->per_session));
230         evas_object_smart_callback_add(cb_session, "changed", NULL, NULL);
231         evas_object_size_hint_align_set(cb_session, EVAS_HINT_FILL, EVAS_HINT_FILL);
232         evas_object_size_hint_weight_set(cb_session, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
233         evas_object_show(cb_session);
234         elm_box_pack_end(box, cb_session);
235
236         if (pdp->popup_type == ACE_BLANKET) {
237             LogDebug("popup_type == ACE_BLANKET");
238             cb_always = elm_check_add(pdp->popup);
239             elm_object_text_set(cb_always, "Remember choice forever");
240             elm_check_state_pointer_set(cb_always, &(pdp->always));
241             evas_object_smart_callback_add(cb_always, "changed", NULL, NULL);
242             evas_object_size_hint_align_set(cb_always, EVAS_HINT_FILL, EVAS_HINT_FILL);
243             evas_object_size_hint_weight_set(cb_always, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
244             evas_object_show(cb_always);
245             elm_box_pack_end(box, cb_always);
246         }
247     }
248
249     elm_object_part_content_set(pdp->popup, "default", box);
250
251     grant_button = elm_button_add(pdp->popup);
252     elm_object_text_set(grant_button, "Grant");
253     elm_object_part_content_set(pdp->popup, "button1", grant_button);
254     evas_object_smart_callback_add(grant_button, "clicked", grant_answer, pdp);
255
256     deny_button = elm_button_add(pdp->popup);
257     elm_object_text_set(deny_button, "Deny");
258     elm_object_part_content_set(pdp->popup, "button2", deny_button);
259     evas_object_smart_callback_add(deny_button, "clicked", deny_answer, pdp);
260
261     evas_object_show(pdp->popup);
262
263     // Showing the popup window
264     evas_object_show(win);
265
266     // Run the efl mainloop
267     elm_run();
268 }
269
270 } // anonymous
271
272
273 EAPI_MAIN int
274 elm_main(int argc , char ** argv)
275 {
276 // int pipe_in and int pipe_out should be passed to Popup via args.
277
278 //  These parameters should be passed to Popup via pipe:
279 //  ace_popup_t             popup_type
280 //  const ace_resource_t    resource_name
281 //  const ace_session_id_t  session_id
282 //  ace_widget_handle_t     handle
283 //  const ace_param_list_t  param_list
284
285     try {
286         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-POPUP-BIN");
287     } Catch(DPL::Exception) {
288         //cannot run logger
289         return ACE_INTERNAL_ERROR;
290     }
291     LogDebug("############################ popup binary ################################");
292
293     if(argc < 3){
294         LogError("To few args passed in exec to popup-bin - should be at least 3:");
295         LogError("(binary-name, pipe_in, pipe_out)");
296         LogError("return ACE_INTERNAL_ERROR");
297         return ACE_INTERNAL_ERROR;
298     }
299     LogDebug("Passed args: " << argv[0] <<", " << argv[1] << ", " << argv[2]);
300
301     int pipe_in;
302     int pipe_out;
303
304     // Parsing args (pipe_in, pipe_out)
305     if ( 0 == sscanf(argv[1], "%d", &pipe_in) ){
306         LogError("Error while parsing pipe_in; return ACE_INTERNAL_ERROR");
307         return ACE_INTERNAL_ERROR;
308     }
309     if ( 0 == sscanf(argv[2], "%d", &pipe_out) ){
310         LogError("Error while parsing pipe_out; return ACE_INTERNAL_ERROR");
311         return ACE_INTERNAL_ERROR;
312     }
313     LogDebug("Parsed pipes: IN: " << pipe_in <<", OUT: " <<  pipe_out);
314
315     int  buff_size = 1024;
316     char line[buff_size];
317
318     struct ace_popup_data pd;
319     struct ace_popup_data *pdp = &pd;
320
321     pdp->popup = NULL;
322
323     ssize_t count = 0;
324     time_t time_start;
325     time(&time_start); // now
326     double timeout = 10.0;
327     // try to read parameters from pipe_in
328     // timeout is set for 10 seconds
329     do {
330         count = TEMP_FAILURE_RETRY(read(pipe_in, line, buff_size));
331         if ( timeout < difftime(time(NULL), time_start) ) {
332             LogError("Timeout reached! Exit popup - ACE_INTERNAL_ERROR");
333             close(pipe_in);
334             close(pipe_out);
335             return ACE_INTERNAL_ERROR;
336         }
337     } while (0 == count);
338     if(count < 0){
339         close(pipe_in);
340         close(pipe_out);
341         LogError("read returned a negative value (" << count <<")");
342         LogError("errno: " << strerror( errno ) );
343         LogError("Exit popup - ACE_INTERNAL_ERROR");
344         return ACE_INTERNAL_ERROR;
345     }
346     LogDebug("Read bytes : " << count << " (in " << difftime(time_start, time(NULL)) << " seconds)");
347     close(pipe_in); // cleanup
348
349     Wrt::Popup::BinaryStream stream;
350     stream.Write(count, static_cast <void *> (line));
351     int popup_type = ACE_ONESHOT;
352     std::string resource_name_str;
353     std::string session_id_str;
354     int handle = 0;
355
356     LogDebug("------- Deserialization -------");
357     // Deserialization order:
358     // popup_type, resource_name, session_id, handle, param_list
359
360     DPL::Deserialization::Deserialize(stream, popup_type);
361     LogDebug("popup_type_int : " << popup_type);
362     pdp->popup_type = static_cast <ace_popup_t> (popup_type);
363
364     DPL::Deserialization::Deserialize(stream, resource_name_str);
365     LogDebug("resource_name_char : " << resource_name_str.c_str());
366     pdp->resource_name =
367             strdup(const_cast <ace_resource_t> (resource_name_str.c_str()));
368
369     DPL::Deserialization::Deserialize(stream, session_id_str);
370     LogDebug("session_id_char : " << session_id_str.c_str());
371     pdp->session_id =
372             strdup(const_cast <ace_session_id_t> (session_id_str.c_str()));
373
374     DPL::Deserialization::Deserialize(stream, handle);
375     LogDebug("handle_int : " << handle);
376     pdp->handle = static_cast <ace_widget_handle_t> (handle);
377
378     if(_ace_params_deserializer(&(pdp->param_list), &stream)){
379         return ACE_INTERNAL_ERROR;
380     }
381
382     pdp->per_session = EINA_FALSE;
383     pdp->always = EINA_FALSE;
384     pdp->validation_return = ACE_ACE_UNKNOWN_ERROR;
385
386     show_popup(pdp); // Showing popup
387
388     // sending validation_result to popup-runner
389     Wrt::Popup::BinaryStream stream_out;
390
391     LogDebug("pdp->validation_result : " << pdp->validation_result);
392     int validation_result_int = (int) pdp->validation_result;
393     LogDebug("validation_result_int : " << validation_result_int);
394     DPL::Serialization::Serialize(stream_out, validation_result_int);
395     if(-1 == TEMP_FAILURE_RETRY(write(pipe_out, stream_out.char_pointer(), stream_out.size()))){
396         LogError("Write to pipe failed!");
397         close(pipe_out);
398         return ACE_INTERNAL_ERROR;
399     }
400     close(pipe_out);
401
402     if (pdp->validation_return == ACE_OK) {
403         LogDebug("ACE_OK");
404     }
405     else if (pdp->validation_return == ACE_INVALID_ARGUMENTS) {
406         LogError("ACE_INVALID_ARGUMENTS");
407     }
408     else if (pdp->validation_return == ACE_INTERNAL_ERROR) {
409         LogError("ACE_INTERNAL_ERROR");
410     }
411     else if (pdp->validation_return == ACE_ACE_UNKNOWN_ERROR) {
412         LogError("ACE_ACE_UNKNOWN_ERROR");
413     }
414     else {
415         LogError("Really unknown error!!!");
416     }
417
418     LogDebug("############################ /popup binary ################################");
419
420     // Shutdown elementary
421     //LogDebug("elm_shutdown()");
422     //elm_shutdown();
423     // This is commented because, it causes that popup exits with 139 code (Segmentatation violation).
424     // Not calling elm_shutdown() should not have any negative consequences because this binary ends
425     // in next line, and system should clear the memory.
426
427     _ace_params_finalize(&(pdp->param_list));
428     return pdp->validation_return;
429 }
430 ELM_MAIN()