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