Tizen 2.1 base
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / ace / popup-runner / popup-runner.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-runner.cpp
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 <iostream>
31 #include <sstream>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34
35 #include <dpl/log/log.h>
36
37 #include "popup-runner.h"
38
39 namespace { // anonymous
40
41 const char *POPUP_EXEC = "/usr/bin/wrt-popup-ace-runtime";
42
43 void _ace_params_serializer (const ace_param_list_t* ace_param_list, Wrt::Popup::BinaryStream *stream){
44
45     LogDebug("_ace_params_serializer");
46
47     if(NULL == ace_param_list || NULL == stream){
48         LogError("*ace_param_list or *stream is NULL; return");
49         return;
50     }
51     LogDebug("Param count : " << ace_param_list->count);
52
53     // serialize ace_param_list->count;
54     size_t count = static_cast <size_t> (ace_param_list->count);
55     DPL::Serialization::Serialize(*stream, count);
56
57     for(size_t i=0; i < count; ++i){
58         std::string name(ace_param_list->items[i].name);
59         DPL::Serialization::Serialize(*stream, name);
60
61         std::string value(ace_param_list->items[i].value);
62         DPL::Serialization::Serialize(*stream, value);
63     }
64 }
65
66 } // anonymous namespace
67
68 namespace Wrt {
69 namespace Popup {
70
71 // BinaryStream class implementation
72 void BinaryStream::Read(size_t num, void * bytes) {
73     size_t max_size = m_data.size();
74     for (size_t i = 0; i < num; ++i) {
75         if( i + m_readPosition >= max_size){
76             return;
77         }
78         static_cast <unsigned char*> (bytes)[i] = m_data[i + m_readPosition];
79     }
80     m_readPosition += num;
81 }
82
83 void BinaryStream::Write(size_t num, const void * bytes) {
84     for (size_t i = 0; i < num; ++i) {
85         m_data.push_back(static_cast <const unsigned char*> (bytes)[i]);
86     }
87 }
88
89 BinaryStream::BinaryStream() {
90     m_readPosition = 0;
91 }
92
93 BinaryStream::~BinaryStream() {
94 }
95
96 const unsigned char* BinaryStream::char_pointer() const {
97     return &m_data[0];
98 }
99
100 size_t BinaryStream::size() const {
101     return m_data.size();
102 }
103 // BinaryStream
104
105 ace_return_t run_popup(
106         ace_popup_t popup_type,
107         const ace_resource_t resource_name,
108         const ace_session_id_t session_id,
109         const ace_param_list_t* ace_param_list,
110         ace_widget_handle_t handle,
111         ace_bool_t* validation_result)
112 {
113     if (    NULL == resource_name  ||
114             NULL == session_id     ||
115             NULL == ace_param_list ||
116             NULL == validation_result )
117     {
118         LogError("run_popup : ACE_INVALID_ARGUMENTS");
119         return ACE_INVALID_ARGUMENTS;
120     }
121     LogDebug("popup_type    : " << popup_type);
122     LogDebug("resource_name : " << resource_name);
123     LogDebug("session_id    : " << session_id);
124     LogDebug("widget handle : " << handle);
125
126     int  popup_type_int      = static_cast <int>    (popup_type);
127     char *resource_name_char = static_cast <char *> (resource_name);
128     char *session_id_char    = static_cast <char *> (session_id);
129     int  handle_int          = static_cast <int>    (handle);
130
131     // serialization
132     Wrt::Popup::BinaryStream stream;
133     DPL::Serialization::Serialize(stream, popup_type_int);
134
135     std::string resource_name_str(resource_name_char);
136     DPL::Serialization::Serialize(stream, resource_name_str);
137
138     std::string session_id_str(session_id_char);
139     DPL::Serialization::Serialize(stream, session_id_str);
140
141     DPL::Serialization::Serialize(stream, handle_int);
142
143     _ace_params_serializer (ace_param_list, &stream);
144
145     int   fd_send_to_child[2];
146     int   fd_send_to_parent[2];
147     pid_t childpid;
148
149     if(0 != pipe(fd_send_to_child)){
150         LogError("Cannot create pipes!");
151         return ACE_INTERNAL_ERROR;
152     }
153     if(0 != pipe(fd_send_to_parent)){
154         LogError("Cannot create pipes!");
155         return ACE_INTERNAL_ERROR;
156     }
157
158     if ((childpid = fork()) == -1) {
159         LogError("Fork() ERROR");
160         return ACE_ACE_UNKNOWN_ERROR;
161     }
162
163     if(childpid == 0) { // Child process
164         LogDebug("Child");
165
166         // read data from parent
167         close(fd_send_to_child[1]);
168
169         // send data to parent
170         close(fd_send_to_parent[0]);
171
172         std::stringstream pipe_in_buff;
173         std::stringstream pipe_out_buff;
174         pipe_in_buff  << fd_send_to_parent[1];
175         pipe_out_buff << fd_send_to_child[0];
176         std::string pipe_in  = pipe_in_buff.str();
177         std::string pipe_out = pipe_out_buff.str();
178
179         LogDebug("Passed file descriptors: " << fd_send_to_child[0] << ", "<< fd_send_to_parent[1]);
180
181         if (execl(POPUP_EXEC, POPUP_EXEC, pipe_out.c_str(), pipe_in.c_str(), NULL) < 0){
182             LogError("execlp FAILED");
183         }
184
185         LogError("This should not happened!!!");
186
187     } // end of child process - from now you can use DEBUG LOGS
188     else { // Parent process
189         LogDebug("Parent");
190
191         int  buff_size = 1024;
192         char result[buff_size];
193         // send data to child
194         close(fd_send_to_child[0]);
195
196         //writing to child
197         LogDebug("Sending message to popup-bin process");
198         if(-1 == TEMP_FAILURE_RETRY(write(fd_send_to_child[1], stream.char_pointer(), stream.size()))){
199             LogError("Write to pipe failed!");
200             return ACE_INTERNAL_ERROR;
201         }
202         close(fd_send_to_child[1]); // cleanup
203         LogDebug("Message has been sent");
204
205         // read data from child
206         close(fd_send_to_parent[1]);
207
208         int status;
209         wait(&status);
210         LogDebug("STATUS EXIT ON POPUP (CHILD): " << status);
211         switch (status){
212
213         case ACE_OK:
214             LogDebug("ACE_OK");
215             break;
216
217         case ACE_INVALID_ARGUMENTS:
218             LogDebug("ACE_INVALID_ARGUMENTS");
219             close(fd_send_to_parent[0]);
220             return static_cast <ace_return_t> (status);
221             break;
222
223         case ACE_INTERNAL_ERROR:
224             LogDebug("ACE_INTERNAL_ERROR");
225             close(fd_send_to_parent[0]);
226             return static_cast <ace_return_t> (status);
227             break;
228
229         case ACE_ACE_UNKNOWN_ERROR:
230             LogDebug("ACE_ACE_UNKNOWN_ERROR");
231             close(fd_send_to_parent[0]);
232             return static_cast <ace_return_t> (status);
233             break;
234
235         default:
236             LogDebug("UNKNOWN_ERROR");
237             close(fd_send_to_parent[0]);
238             status = (int) ACE_ACE_UNKNOWN_ERROR;
239             return static_cast <ace_return_t> (status);
240             break;
241         }
242
243         int count;
244         count = TEMP_FAILURE_RETRY(read(fd_send_to_parent[0], result, buff_size));
245         close(fd_send_to_parent[0]); // cleanup
246         int validation_result_int;
247
248         if(0 < count){
249             BinaryStream stream_in;
250             stream_in.Write(count, result);
251             LogDebug("RESULT FROM POPUP (CHILD) : [ " << count << " ]");
252             DPL::Deserialization::Deserialize(stream_in, validation_result_int);
253             *validation_result = static_cast <ace_bool_t> (validation_result_int);
254
255             LogDebug("validation_result :");
256             switch (*validation_result){
257             case ACE_FALSE:
258                 LogDebug("ACE_FALSE");
259                 break;
260             case ACE_TRUE:
261                 LogDebug("ACE_TRUE");
262                 break;
263             default:
264                 LogDebug("UNKNOWN - DEFAULT");
265                 break;
266             }
267         }
268         else {
269             LogDebug("count = " << count);
270             LogDebug("UNKNOWN_ERROR");
271             return ACE_ACE_UNKNOWN_ERROR;
272         }
273
274         LogDebug("popup-runner: EXIT");
275         return (ace_return_t) status;
276     }
277
278     LogError("This should not happend!!!");
279     return ACE_ACE_UNKNOWN_ERROR;
280 }
281
282 } // Popup
283 } // Wrt