2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Janusz Kozerski (j.kozerski@samsung.com)
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.
34 #include <Elementary.h>
36 #include <dpl/log/log.h>
37 #include <dpl/serialization.h>
38 #include <ace_api_common.h>
39 #include <ace_api_popup_validation.h>
41 #include "popup-runner.h"
44 namespace { // anonymous
46 static void set_validity_from_checkbox(struct ace_popup_data *pdp) {
49 LogError("pdp is NULL; return");
54 LogDebug("Remember ALWAYS");
55 pdp->remember_choice = ACE_ALWAYS;
58 if (pdp->per_session) {
59 LogDebug("Remember PER_SESSION");
60 pdp->remember_choice = ACE_PER_SESSION;
63 LogDebug("Remember ONCE");
64 pdp->remember_choice = ACE_ONCE;
68 static void on_done(void) {
69 // Quit the efl-mainloop
70 LogDebug("elm_exit()");
74 static void grant_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
76 LogDebug("grant_answer");
78 LogError("data is NULL; return");
81 struct ace_popup_data *pdp = static_cast <struct ace_popup_data *> (data);
83 set_validity_from_checkbox(pdp);
85 ace_popup_validation_initialize();
86 pdp->validation_return = ace_validate_answer(
93 &(pdp->validation_result));
94 ace_popup_validation_shutdown();
99 static void deny_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
101 LogDebug("deny_answer");
103 LogError("data is NULL; return");
106 struct ace_popup_data *pdp = static_cast <struct ace_popup_data *> (data);
108 set_validity_from_checkbox(pdp);
110 ace_popup_validation_initialize();
111 pdp->validation_return = ace_validate_answer(
113 pdp->remember_choice,
118 &(pdp->validation_result));
119 ace_popup_validation_shutdown();
124 static int _ace_params_deserializer(ace_param_list_t* ace_param_list, Wrt::Popup::BinaryStream *stream){
126 LogDebug("_ace_params_deserializer");
128 if(NULL == ace_param_list || NULL == stream){
129 LogError("ace_param_list or stream is NULL; return -1");
133 // deserialize ace_param_list->count;
135 DPL::Deserialization::Deserialize(*stream, count);
136 ace_param_list->count = count;
137 LogDebug("count : " << count);
142 ace_param_list->items = NULL;
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));
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()));
153 DPL::Deserialization::Deserialize(*stream, value);
154 ace_param_list->items[i].value =
155 strdup(const_cast <char *> (value.c_str()));
160 static void _ace_params_finalize(ace_param_list_t* ace_param_list) {
161 if (!ace_param_list || !ace_param_list->items) {
162 LogDebug("List is null, nothing to do");
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);
169 free(ace_param_list->items);
170 ace_param_list->items = NULL;
171 ace_param_list->count = 0;
174 static void show_popup(struct ace_popup_data *pdp) {
175 LogDebug("show_popup()");
178 LogError("pdp is NULL; return");
182 const char *resource_type = static_cast <char *> (pdp->resource_name);
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;
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);
200 pdp->popup = elm_popup_add(win);
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);
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);
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);
217 elm_object_text_set(label, 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);
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);
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);
249 elm_object_part_content_set(pdp->popup, "default", box);
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);
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);
261 evas_object_show(pdp->popup);
263 // Showing the popup window
264 evas_object_show(win);
266 // Run the efl mainloop
274 elm_main(int argc , char ** argv)
276 UNHANDLED_EXCEPTION_HANDLER_BEGIN
278 // int pipe_in and int pipe_out should be passed to Popup via args.
280 // These parameters should be passed to Popup via pipe:
281 // ace_popup_t popup_type
282 // const ace_resource_t resource_name
283 // const ace_session_id_t session_id
284 // ace_widget_handle_t handle
285 // const ace_param_list_t param_list
288 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-POPUP-BIN");
289 } Catch(DPL::Exception) {
291 return ACE_INTERNAL_ERROR;
293 LogDebug("############################ popup binary ################################");
296 LogError("To few args passed in exec to popup-bin - should be at least 3:");
297 LogError("(binary-name, pipe_in, pipe_out)");
298 LogError("return ACE_INTERNAL_ERROR");
299 return ACE_INTERNAL_ERROR;
301 LogDebug("Passed args: " << argv[0] <<", " << argv[1] << ", " << argv[2]);
306 // Parsing args (pipe_in, pipe_out)
307 if ( 0 == sscanf(argv[1], "%d", &pipe_in) ){
308 LogError("Error while parsing pipe_in; return ACE_INTERNAL_ERROR");
309 return ACE_INTERNAL_ERROR;
311 if ( 0 == sscanf(argv[2], "%d", &pipe_out) ){
312 LogError("Error while parsing pipe_out; return ACE_INTERNAL_ERROR");
313 return ACE_INTERNAL_ERROR;
315 LogDebug("Parsed pipes: IN: " << pipe_in <<", OUT: " << pipe_out);
317 int buff_size = 1024;
318 char line[buff_size];
320 struct ace_popup_data pd;
321 struct ace_popup_data *pdp = &pd;
327 time(&time_start); // now
328 double timeout = 10.0;
329 // try to read parameters from pipe_in
330 // timeout is set for 10 seconds
332 count = TEMP_FAILURE_RETRY(read(pipe_in, line, buff_size));
333 if ( timeout < difftime(time(NULL), time_start) ) {
334 LogError("Timeout reached! Exit popup - ACE_INTERNAL_ERROR");
337 return ACE_INTERNAL_ERROR;
339 } while (0 == count);
343 LogError("read returned a negative value (" << count <<")");
344 LogError("errno: " << strerror( errno ) );
345 LogError("Exit popup - ACE_INTERNAL_ERROR");
346 return ACE_INTERNAL_ERROR;
348 LogDebug("Read bytes : " << count << " (in " << difftime(time_start, time(NULL)) << " seconds)");
349 close(pipe_in); // cleanup
351 Wrt::Popup::BinaryStream stream;
352 stream.Write(count, static_cast <void *> (line));
353 int popup_type = ACE_ONESHOT;
354 std::string resource_name_str;
355 std::string session_id_str;
358 LogDebug("------- Deserialization -------");
359 // Deserialization order:
360 // popup_type, resource_name, session_id, handle, param_list
362 DPL::Deserialization::Deserialize(stream, popup_type);
363 LogDebug("popup_type_int : " << popup_type);
364 pdp->popup_type = static_cast <ace_popup_t> (popup_type);
366 DPL::Deserialization::Deserialize(stream, resource_name_str);
367 LogDebug("resource_name_char : " << resource_name_str.c_str());
369 strdup(const_cast <ace_resource_t> (resource_name_str.c_str()));
371 DPL::Deserialization::Deserialize(stream, session_id_str);
372 LogDebug("session_id_char : " << session_id_str.c_str());
374 strdup(const_cast <ace_session_id_t> (session_id_str.c_str()));
376 DPL::Deserialization::Deserialize(stream, handle);
377 LogDebug("handle_int : " << handle);
378 pdp->handle = static_cast <ace_widget_handle_t> (handle);
380 if(_ace_params_deserializer(&(pdp->param_list), &stream)){
381 return ACE_INTERNAL_ERROR;
384 pdp->per_session = EINA_FALSE;
385 pdp->always = EINA_FALSE;
386 pdp->validation_return = ACE_ACE_UNKNOWN_ERROR;
388 show_popup(pdp); // Showing popup
390 // sending validation_result to popup-runner
391 Wrt::Popup::BinaryStream stream_out;
393 LogDebug("pdp->validation_result : " << pdp->validation_result);
394 int validation_result_int = (int) pdp->validation_result;
395 LogDebug("validation_result_int : " << validation_result_int);
396 DPL::Serialization::Serialize(stream_out, validation_result_int);
397 if(-1 == TEMP_FAILURE_RETRY(write(pipe_out, stream_out.char_pointer(), stream_out.size()))){
398 LogError("Write to pipe failed!");
400 return ACE_INTERNAL_ERROR;
404 if (pdp->validation_return == ACE_OK) {
407 else if (pdp->validation_return == ACE_INVALID_ARGUMENTS) {
408 LogError("ACE_INVALID_ARGUMENTS");
410 else if (pdp->validation_return == ACE_INTERNAL_ERROR) {
411 LogError("ACE_INTERNAL_ERROR");
413 else if (pdp->validation_return == ACE_ACE_UNKNOWN_ERROR) {
414 LogError("ACE_ACE_UNKNOWN_ERROR");
417 LogError("Really unknown error!!!");
420 LogDebug("############################ /popup binary ################################");
422 // Shutdown elementary
423 //LogDebug("elm_shutdown()");
425 // This is commented because, it causes that popup exits with 139 code (Segmentatation violation).
426 // Not calling elm_shutdown() should not have any negative consequences because this binary ends
427 // in next line, and system should clear the memory.
429 _ace_params_finalize(&(pdp->param_list));
430 return pdp->validation_return;
432 UNHANDLED_EXCEPTION_HANDLER_END