Tizen 2.1 base
[platform/framework/web/wrt-plugins-common.git] / src / wrt-popup / wrt / popup-runner / PopupInvoker.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 #include "PopupInvoker.h"
18 #include <sstream>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <dpl/log/log.h>
22 #include <dpl/waitable_handle.h>
23 #include <dpl/binary_queue.h>
24 #include <dpl/serialization.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include "PopupEnum.h"
28 #include "PopupSerializer.h"
29
30 namespace {
31 const char *POPUP_EXEC = "/usr/bin/wrt-popup-wrt-runtime";
32 }
33
34 namespace Wrt {
35 namespace Popup {
36
37 PopupInvoker::PopupInvoker() :
38     m_inputName(tmpnam(NULL)),
39     m_outputName(tmpnam(NULL))
40 {
41     Try
42     {
43         m_input.Create(m_inputName);
44         m_output.Create(m_outputName);
45         LogDebug("Pipes created");
46     }
47     Catch (DPL::Exception)
48     {
49         LogError("Cannot create pipes");
50     }
51 }
52
53 PopupInvoker::~PopupInvoker()
54 {
55     Try
56     {
57         m_input.Destroy(m_inputName);
58         m_output.Destroy(m_outputName);
59         LogDebug("Pipes destroyed");
60     }
61     Catch (DPL::Exception)
62     {
63         LogError("Cannot destroy pipes");
64     }
65 }
66
67 bool PopupInvoker::askYesNo(const std::string& title, const std::string& message)
68 {
69     Try
70     {
71         DPL::BinaryQueue data;
72         PopupSerializer::appendArg(YES_NO_PROMPT, data);
73         PopupSerializer::appendArg(title, data);
74         PopupSerializer::appendArg(message, data);
75         DPL::NamedInputPipe tmp;
76         tmp.Open(m_outputName);
77         m_output.Open(m_outputName);
78         m_input.Open(m_inputName);
79         m_output.Write(data, data.Size());
80
81         executePopup();
82
83         //Result from popup application is available. Read it.
84         DPL::BinaryQueueAutoPtr resultData =
85             m_input.Read(std::numeric_limits<std::size_t>::max());
86         const int result = PopupSerializer::getIntArg(*resultData);
87
88         LogDebug("Popup result is: " << result);
89
90         Assert(resultData->Empty());
91
92         tmp.Close();
93         m_input.Close();
94         m_output.Close();
95
96         return (!!result);
97     }
98     Catch(DPL::Exception)
99     {
100         LogError("error occured");
101     }
102
103     return false;
104 }
105
106 void PopupInvoker::showInfo(const std::string& title,
107                             const std::string& message,
108                             const std::string& buttonLabel)
109 {
110     Try
111     {
112         DPL::BinaryQueue data;
113         PopupSerializer::appendArg(INFO_PROMPT, data);
114         PopupSerializer::appendArg(title, data);
115         PopupSerializer::appendArg(message, data);
116         PopupSerializer::appendArg(buttonLabel, data);
117         DPL::NamedInputPipe tmp;
118         tmp.Open(m_outputName);
119         m_output.Open(m_outputName);
120         m_input.Open(m_inputName);
121         m_output.Write(data, data.Size());
122
123         executePopup();
124
125         //ignore result
126
127         tmp.Close();
128         m_input.Close();
129         m_output.Close();
130     }
131     Catch(DPL::Exception)
132     {
133         LogError("error occured");
134     }
135 }
136
137 PopupResponse PopupInvoker::askYesNoCheckbox(const std::string& title,
138     const std::string& message, const std::string& checkboxLabel)
139 {
140     Try
141     {
142         DPL::BinaryQueue data;
143         PopupSerializer::appendArg(YES_NO_CHECK_PROMPT, data);
144         PopupSerializer::appendArg(title, data);
145         PopupSerializer::appendArg(message, data);
146         PopupSerializer::appendArg(checkboxLabel, data);
147         DPL::NamedInputPipe tmp;
148         tmp.Open(m_outputName);
149         m_output.Open(m_outputName);
150         m_input.Open(m_inputName);
151         m_output.Write(data, data.Size());
152
153         executePopup();
154
155         //Result from popup application is available. Read it.
156         DPL::BinaryQueueAutoPtr resultData =
157             m_input.Read(std::numeric_limits<std::size_t>::max());
158         const int result = PopupSerializer::getIntArg(*resultData);
159         const int rememberResult = PopupSerializer::getIntArg(*resultData);
160
161         LogDebug("Popup result is: " << result << " remeber: " << rememberResult);
162
163         Assert(resultData->Empty());
164         tmp.Close();
165         m_input.Close();
166         m_output.Close();
167
168         if (1 == result) {
169             if (rememberResult == 1) {
170                 return YES_DO_REMEMBER;
171             } else {
172                 return YES_DONT_REMEMBER;
173             }
174         } else {
175             if (rememberResult == 1) {
176                 return NO_DO_REMEMBER;
177             } else {
178                 return NO_DONT_REMEMBER;
179             }
180         }
181     }
182     Catch(DPL::Exception)
183     {
184         LogError("error occured");
185     }
186     return NO_DONT_REMEMBER;
187 }
188
189 void PopupInvoker::executePopup()
190 {
191     pid_t pid = fork();
192     if (pid == -1)
193     {
194         //error occured
195         LogError("Cannot display popup!");
196         Assert(false);
197     }
198     if (pid == 0)
199     {
200         //child process
201         int ret = execl(POPUP_EXEC,
202                         POPUP_EXEC,
203                         m_outputName.c_str(),
204                         m_inputName.c_str(),
205                         NULL);
206         if (ret == -1) {
207             //execl returns -1 on error
208             LogError("Cannot display popup!");
209             Assert(false);
210         }
211     }
212
213     DPL::WaitableHandle handle = m_input.WaitableReadHandle();
214     DPL::WaitForSingleHandle(handle);
215 }
216
217 } // Popup
218 } // Wrt