Update wrt-plugins-common_0.3.60
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / 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
147     for(size_t i=0; i < count; ++i){
148         DPL::Deserialization::Deserialize(*stream, name);
149         ace_param_list->items[i].name = const_cast <char *> (name.c_str());
150
151         DPL::Deserialization::Deserialize(*stream, value);
152         ace_param_list->items[i].value = const_cast <char *> (value.c_str());
153     }
154     return 0;
155 }
156
157 static void show_popup(struct ace_popup_data *pdp) {
158     LogDebug("show_popup()");
159
160     if(NULL == pdp){
161         LogError("pdp is NULL; return");
162         return;
163     }
164
165     const char *resource_type = static_cast <char *> (pdp->resource_name);
166
167     Evas_Object *win          = NULL;
168     Evas_Object *cb_session   = NULL;
169     Evas_Object *cb_always    = NULL;
170     Evas_Object *box          = NULL;
171     Evas_Object *label        = NULL;
172     Evas_Object *grant_button = NULL;
173     Evas_Object *deny_button  = NULL;
174     pdp->per_session          = EINA_FALSE;
175     pdp->always               = EINA_FALSE;
176
177     win = elm_win_add(NULL, "The wrt-client popup", ELM_WIN_NOTIFICATION);
178     elm_win_autodel_set(win, EINA_TRUE);
179     elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
180     evas_object_show(win);
181     elm_win_indicator_opacity_set(win, ELM_WIN_INDICATOR_TRANSLUCENT);
182
183     pdp->popup = elm_popup_add(win);
184
185     box = elm_box_add(pdp->popup);
186     evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0);
187     evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0.0);
188
189     label = elm_label_add(pdp->popup);
190     elm_object_style_set(label, "popup_description/default");
191     elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
192     char *buff = NULL;
193     if(-1 == asprintf(&buff, "Application need an access to %s.<br>Grant or deny?", resource_type)){
194         LogError("asprintf failed - returned -1");
195         evas_object_del(label);
196         evas_object_del(pdp->popup);
197         evas_object_del(win);
198         return;
199     }
200     elm_object_text_set(label, buff);
201     free(buff);
202     evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
203     evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
204     evas_object_show(label);
205     elm_box_pack_end(box, label);
206
207     LogDebug("popup_type == " << pdp->popup_type);
208     if (pdp->popup_type == ACE_SESSION || pdp->popup_type == ACE_BLANKET) {
209         LogDebug("popup_type == ACE_SESSION || ACE_BLANKET");
210         cb_session = elm_check_add(pdp->popup);
211         elm_object_text_set(cb_session, "Remember choice for this session");
212         elm_check_state_pointer_set(cb_session, &(pdp->per_session));
213         evas_object_smart_callback_add(cb_session, "changed", NULL, NULL);
214         evas_object_size_hint_align_set(cb_session, EVAS_HINT_FILL, EVAS_HINT_FILL);
215         evas_object_size_hint_weight_set(cb_session, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
216         evas_object_show(cb_session);
217         elm_box_pack_end(box, cb_session);
218
219         if (pdp->popup_type == ACE_BLANKET) {
220             LogDebug("popup_type == ACE_BLANKET");
221             cb_always = elm_check_add(pdp->popup);
222             elm_object_text_set(cb_always, "Remember choice forever");
223             elm_check_state_pointer_set(cb_always, &(pdp->always));
224             evas_object_smart_callback_add(cb_always, "changed", NULL, NULL);
225             evas_object_size_hint_align_set(cb_always, EVAS_HINT_FILL, EVAS_HINT_FILL);
226             evas_object_size_hint_weight_set(cb_always, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
227             evas_object_show(cb_always);
228             elm_box_pack_end(box, cb_always);
229         }
230     }
231
232     elm_object_part_content_set(pdp->popup, "default", box);
233
234     grant_button = elm_button_add(pdp->popup);
235     elm_object_text_set(grant_button, "Grant");
236     elm_object_part_content_set(pdp->popup, "button1", grant_button);
237     evas_object_smart_callback_add(grant_button, "clicked", grant_answer, pdp);
238
239     deny_button = elm_button_add(pdp->popup);
240     elm_object_text_set(deny_button, "Deny");
241     elm_object_part_content_set(pdp->popup, "button2", deny_button);
242     evas_object_smart_callback_add(deny_button, "clicked", deny_answer, pdp);
243
244     evas_object_show(pdp->popup);
245
246     // Showing the popup window
247     evas_object_show(win);
248
249     // Run the efl mainloop
250     elm_run();
251 }
252
253 } // anonymous
254
255
256 EAPI_MAIN int
257 elm_main(int argc , char ** argv)
258 {
259 // int pipe_in and int pipe_out should be passed to Popup via args.
260
261 //  These parameters should be passed to Popup via pipe:
262 //  ace_popup_t             popup_type
263 //  const ace_resource_t    resource_name
264 //  const ace_session_id_t  session_id
265 //  ace_widget_handle_t     handle
266 //  const ace_param_list_t  param_list
267
268
269     DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-POPUP-BIN");
270     LogDebug("############################ popup binary ################################");
271
272     if(argc < 3){
273         LogError("To few args passed in exec to popup-bin - should be at least 3:");
274         LogError("(binary-name, pipe_in, pipe_out)");
275         LogError("return ACE_INTERNAL_ERROR");
276         return ACE_INTERNAL_ERROR;
277     }
278     LogDebug("Passed args: " << argv[0] <<", " << argv[1] << ", " << argv[2]);
279
280     int pipe_in;
281     int pipe_out;
282
283     // Parsing args (pipe_in, pipe_out)
284     if ( 0 == sscanf(argv[1], "%d", &pipe_in) ){
285         LogError("Error while parsing pipe_in; return ACE_INTERNAL_ERROR");
286         return ACE_INTERNAL_ERROR;
287     }
288     if ( 0 == sscanf(argv[2], "%d", &pipe_out) ){
289         LogError("Error while parsing pipe_out; return ACE_INTERNAL_ERROR");
290         return ACE_INTERNAL_ERROR;
291     }
292     LogDebug("Parsed pipes: IN: " << pipe_in <<", OUT: " <<  pipe_out);
293
294     int  buff_size = 1024;
295     char line[buff_size];
296
297     struct ace_popup_data pd;
298     struct ace_popup_data *pdp = &pd;
299
300     pdp->popup = NULL;
301
302     ssize_t count = 0;
303     time_t time_start;
304     time(&time_start); // now
305     double timeout = 10.0;
306     // try to read parameters from pipe_in
307     // timeout is set for 10 seconds
308     do {
309         count = TEMP_FAILURE_RETRY(read(pipe_in, line, buff_size));
310         if ( timeout < difftime(time(NULL), time_start) ) {
311             LogError("Timeout reached! Exit popup - ACE_INTERNAL_ERROR");
312             close(pipe_in);
313             close(pipe_out);
314             return ACE_INTERNAL_ERROR;
315         }
316     } while (0 == count);
317     if(count < 0){
318         close(pipe_in);
319         close(pipe_out);
320         LogError("read returned a negative value (" << count <<")");
321         LogError("errno: " << strerror( errno ) );
322         LogError("Exit popup - ACE_INTERNAL_ERROR");
323         return ACE_INTERNAL_ERROR;
324     }
325     LogDebug("Read bytes : " << count << " (in " << difftime(time_start, time(NULL)) << " seconds)");
326     close(pipe_in); // cleanup
327
328     Wrt::Popup::BinaryStream stream;
329     stream.Write(count, static_cast <void *> (line));
330     int popup_type = ACE_ONESHOT;
331     std::string resource_name_str;
332     std::string session_id_str;
333     int handle = 0;
334
335     LogDebug("------- Deserialization -------");
336     // Deserialization order:
337     // popup_type, resource_name, session_id, handle, param_list
338
339     DPL::Deserialization::Deserialize(stream, popup_type);
340     LogDebug("popup_type_int : " << popup_type);
341     pdp->popup_type = static_cast <ace_popup_t> (popup_type);
342
343     DPL::Deserialization::Deserialize(stream, resource_name_str);
344     LogDebug("resource_name_char : " << resource_name_str.c_str());
345     pdp->resource_name = const_cast <ace_resource_t> (resource_name_str.c_str());
346
347     DPL::Deserialization::Deserialize(stream, session_id_str);
348     LogDebug("session_id_char : " << session_id_str.c_str());
349     pdp->session_id = const_cast <ace_session_id_t> (session_id_str.c_str());
350
351     DPL::Deserialization::Deserialize(stream, handle);
352     LogDebug("handle_int : " << handle);
353     pdp->handle = static_cast <ace_widget_handle_t> (handle);
354
355     if(_ace_params_deserializer(&(pdp->param_list), &stream)){
356         return ACE_INTERNAL_ERROR;
357     }
358
359     pdp->per_session = EINA_FALSE;
360     pdp->always = EINA_FALSE;
361     pdp->validation_return = ACE_ACE_UNKNOWN_ERROR;
362
363     show_popup(pdp); // Showing popup
364
365     // sending validation_result to popup-runner
366     Wrt::Popup::BinaryStream stream_out;
367
368     LogDebug("pdp->validation_result : " << pdp->validation_result);
369     int validation_result_int = (int) pdp->validation_result;
370     LogDebug("validation_result_int : " << validation_result_int);
371     DPL::Serialization::Serialize(stream_out, validation_result_int);
372     if(-1 == TEMP_FAILURE_RETRY(write(pipe_out, stream_out.char_pointer(), stream_out.size()))){
373         LogError("Write to pipe failed!");
374         close(pipe_out);
375         return ACE_INTERNAL_ERROR;
376     }
377     close(pipe_out);
378
379     if (pdp->validation_return == ACE_OK) {
380         LogDebug("ACE_OK");
381     }
382     else if (pdp->validation_return == ACE_INVALID_ARGUMENTS) {
383         LogError("ACE_INVALID_ARGUMENTS");
384     }
385     else if (pdp->validation_return == ACE_INTERNAL_ERROR) {
386         LogError("ACE_INTERNAL_ERROR");
387     }
388     else if (pdp->validation_return == ACE_ACE_UNKNOWN_ERROR) {
389         LogError("ACE_ACE_UNKNOWN_ERROR");
390     }
391     else {
392         LogError("Really unknown error!!!");
393     }
394
395     LogDebug("############################ /popup binary ################################");
396
397     // Shutdown elementary
398     //LogDebug("elm_shutdown()");
399     //elm_shutdown();
400     // This is commented because, it causes that popup exits with 139 code (Segmentatation violation).
401     // Not calling elm_shutdown() should not have any negative consequences because this binary ends
402     // in next line, and system should clear the memory.
403
404     return pdp->validation_return;
405 }
406 ELM_MAIN()