Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_wearable / 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 <dpl/exception.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include "PopupEnum.h"
29 #include "PopupSerializer.h"
30
31 namespace {
32 const char *POPUP_EXEC = "/usr/bin/wrt-popup-wrt-runtime";
33 }
34
35 namespace Wrt {
36 namespace Popup {
37 PopupInvoker::PopupInvoker()
38 {
39     char tmp[L_tmpnam + 1];
40     if (NULL == tmpnam(tmp))
41         ThrowMsg(DPL::Exception, "Failed to get pipe name");
42     m_inputName = tmp;
43
44     if (NULL == tmpnam(tmp))
45         ThrowMsg(DPL::Exception, "Failed to get pipe name");
46     m_outputName = tmp;
47
48     m_input.Create(m_inputName);
49     m_output.Create(m_outputName);
50     LogDebug("Pipes created");
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,
68                             const std::string& message)
69 {
70     Try
71     {
72         DPL::BinaryQueue data;
73         PopupSerializer::appendArg(YES_NO_PROMPT, data);
74         PopupSerializer::appendArg(title, data);
75         PopupSerializer::appendArg(message, data);
76         DPL::NamedInputPipe tmp;
77         tmp.Open(m_outputName);
78         m_output.Open(m_outputName);
79         m_input.Open(m_inputName);
80         m_output.Write(data, data.Size());
81
82         executePopup();
83
84         //Result from popup application is available. Read it.
85         DPL::BinaryQueueAutoPtr resultData =
86             m_input.Read(std::numeric_limits<std::size_t>::max());
87         const int success = PopupSerializer::getIntArg(*resultData);
88         bool retVal = false;
89         if (success) {
90             const int result = PopupSerializer::getIntArg(*resultData);
91
92             LogDebug("Popup result is: " << result);
93
94             Assert(resultData->Empty());
95             retVal = (!!result);
96         } else {
97             LogWarning("Failed to show popup.");
98         }
99
100         tmp.Close();
101         m_input.Close();
102         m_output.Close();
103
104         return retVal;
105     }
106     Catch(DPL::Exception)
107     {
108         LogError("error occured");
109     }
110
111     return false;
112 }
113
114 void PopupInvoker::showInfo(const std::string& title,
115                             const std::string& message,
116                             const std::string& buttonLabel)
117 {
118     Try
119     {
120         DPL::BinaryQueue data;
121         PopupSerializer::appendArg(INFO_PROMPT, data);
122         PopupSerializer::appendArg(title, data);
123         PopupSerializer::appendArg(message, data);
124         PopupSerializer::appendArg(buttonLabel, data);
125         DPL::NamedInputPipe tmp;
126         tmp.Open(m_outputName);
127         m_output.Open(m_outputName);
128         m_input.Open(m_inputName);
129         m_output.Write(data, data.Size());
130
131         executePopup();
132         DPL::BinaryQueueAutoPtr resultData =
133             m_input.Read(std::numeric_limits<std::size_t>::max());
134         const int success = PopupSerializer::getIntArg(*resultData);
135         if (!success) {
136             LogWarning("Failed to show popup.");
137         }
138         //ignore result
139
140         tmp.Close();
141         m_input.Close();
142         m_output.Close();
143     }
144     Catch(DPL::Exception)
145     {
146         LogError("error occured");
147     }
148 }
149
150 PopupResponse PopupInvoker::askYesNoCheckbox(const std::string& title,
151                                              const std::string& message,
152                                              const std::string& checkboxLabel)
153 {
154     Try
155     {
156         DPL::BinaryQueue data;
157         PopupSerializer::appendArg(YES_NO_CHECK_PROMPT, data);
158         PopupSerializer::appendArg(title, data);
159         PopupSerializer::appendArg(message, data);
160         PopupSerializer::appendArg(checkboxLabel, data);
161         DPL::NamedInputPipe tmp;
162         tmp.Open(m_outputName);
163         m_output.Open(m_outputName);
164         m_input.Open(m_inputName);
165         m_output.Write(data, data.Size());
166
167         executePopup();
168
169         //Result from popup application is available. Read it.
170         DPL::BinaryQueueAutoPtr resultData =
171             m_input.Read(std::numeric_limits<std::size_t>::max());
172         const int success = PopupSerializer::getIntArg(*resultData);
173         if (success) {
174             const int result = PopupSerializer::getIntArg(*resultData);
175             const int rememberResult = PopupSerializer::getIntArg(*resultData);
176
177             LogDebug(
178                 "Popup result is: " << result << " remeber: " << rememberResult);
179
180             Assert(resultData->Empty());
181             tmp.Close();
182             m_input.Close();
183             m_output.Close();
184
185             if (1 == result) {
186                 if (rememberResult == 1) {
187                     return YES_DO_REMEMBER;
188                 } else {
189                     return YES_DONT_REMEMBER;
190                 }
191             } else {
192                 if (rememberResult == 1) {
193                     return NO_DO_REMEMBER;
194                 } else {
195                     return NO_DONT_REMEMBER;
196                 }
197             }
198         } else {
199             LogWarning("Popup failed to execute.");
200             tmp.Close();
201             m_input.Close();
202             m_output.Close();
203             return NO_DONT_REMEMBER;
204         }
205     }
206     Catch(DPL::Exception)
207     {
208         LogError("error occured");
209     }
210     return NO_DONT_REMEMBER;
211 }
212
213 void PopupInvoker::executePopup()
214 {
215     pid_t pid = fork();
216     if (pid == -1) {
217         //error occured
218         LogError("Failed to create popup process.");
219         Assert(false);
220     }
221     if (pid == 0) {
222         //child process
223         int ret = execl(POPUP_EXEC,
224                         POPUP_EXEC,
225                         m_outputName.c_str(),
226                         m_inputName.c_str(),
227                         NULL);
228         if (ret == -1) {
229             //execl returns -1 on error
230             LogError("Failed to set popup binary");
231             //write something to pipe to unblock caller process
232             DPL::NamedOutputPipe errOut;
233             errOut.Open(m_inputName);
234             DPL::BinaryQueue data;
235             PopupSerializer::appendArg(false, data);
236             errOut.Write(data, data.Size());
237             errOut.Close();
238
239             Assert(false);
240         }
241     }
242
243     DPL::WaitableHandle handle = m_input.WaitableReadHandle();
244     DPL::WaitForSingleHandle(handle);
245 }
246 } // Popup
247 } // Wrt