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