Update wrt_0.8.85
[platform/framework/web/wrt.git] / src / wrt-client / wrt-client.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 #include "wrt-client.h"
17 #include <cstdlib>
18 #include <cstdio>
19 #include <string>
20 #include <dpl/log/log.h>
21 #include <dpl/optional_typedefs.h>
22 #include <common/application_data.h>
23 #include <core_module.h>
24
25 WrtClient::WrtClient(int argc, char **argv) :
26     Application(argc, argv, "wrt-client", false),
27     DPL::TaskDecl<WrtClient>(this),
28     m_handle(-1),
29     m_launched(false),
30     m_initializing(false),
31     m_initialized(false),
32     m_sdkLauncherPid(0),
33     m_debugMode(false),
34     m_debuggerPort(0),
35     m_returnStatus(ReturnStatus::Succeeded),
36     m_widgetState(WidgetState::WidgetState_Stopped)
37 {
38     Touch();
39     LogDebug("App Created");
40 }
41
42 WrtClient::~WrtClient()
43 {
44     LogDebug("App Finished");
45 }
46
47 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
48 {
49     return m_returnStatus;
50 }
51
52 void WrtClient::OnStop()
53 {
54     LogInfo("Stopping Dummy Client");
55 }
56
57
58 void WrtClient::OnCreate()
59 {
60     LogInfo("On Create");
61 }
62
63
64 void WrtClient::OnResume()
65 {
66     if (m_widgetState != WidgetState_Suspended) {
67         LogWarning("Widget is not suspended, resuming was skipped");
68         return;
69     }
70     m_widget->Resume();
71     m_widgetState = WidgetState_Running;
72 }
73
74
75 void WrtClient::OnPause()
76 {
77     if (m_widgetState != WidgetState_Running) {
78         LogWarning("Widget is not running to be suspended");
79         return;
80     }
81     m_widget->Suspend();
82     m_widgetState = WidgetState_Suspended;
83 }
84
85 void WrtClient::OnReset(bundle *b)
86 {
87     LogDebug("OnReset");
88     // bundle argument is freed after OnReset() is returned
89     // So bundle duplication is needed
90     ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
91
92     if (true == m_initializing) {
93         LogDebug("can not handle reset event");
94         return;
95     }
96     if (true == m_launched) {
97         if (m_widgetState == WidgetState_Stopped) {
98             LogError("Widget is not running to be reset");
99             return;
100         }
101         m_widget->Reset();
102         m_widgetState = WidgetState_Running;
103     } else {
104         if (true == checkArgument())
105         {
106             setStep();
107         }
108         else
109         {
110             showHelpAndQuit();
111         }
112     }
113 }
114
115 void WrtClient::OnTerminate()
116 {
117     LogDebug("Wrt Shutdown now");
118     shutdownStep();
119 }
120
121 void WrtClient::showHelpAndQuit()
122 {
123     printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
124            "launch widgets.\n"
125            "Mandatory arguments to long options are mandatory for short "
126            "options too.\n"
127            "  -h,    --help                                 show this help\n"
128            "  -l,    --launch                               "
129            "launch widget with given ID\n"
130            "\n");
131
132     Quit();
133 }
134
135 bool WrtClient::checkArgument()
136 {
137     LogInfo("checkArgument");
138
139     std::string arg = m_argv[0];
140
141     if (arg.empty()) {
142         return false;
143     }
144
145     if (arg.find("wrt-client") != std::string::npos)
146     {
147         if (m_argc <= 1) {
148             return false;
149         }
150
151         arg = m_argv[1];
152
153         if (arg == "-h" || arg == "--help") {
154             // Just show help
155             return false;
156         } else if (arg == "-l" || arg == "--launch") {
157             if (m_argc != 3) {
158                 return false;
159             }
160             m_handle = atoi(m_argv[2]);
161         } else {
162             return false;
163         }
164     } else {
165         size_t pos = arg.find_last_of('/');
166
167         if (pos != std::string::npos) {
168             arg = arg.erase(0, pos + 1);
169         }
170
171         // Launch widget based on application basename
172         if (sscanf(arg.c_str(), "%i", &m_handle) != 1) {
173             printf("failed: invalid widget handle\n");
174             return false;
175         }
176
177         LogDebug("Widget Id: " << m_handle << " (" << arg << ")");
178     }
179
180     return true;
181 }
182
183 void WrtClient::setStep()
184 {
185     LogInfo("setStep");
186
187     AddStep(&WrtClient::initStep);
188
189     setSdkLauncherDebugData();
190
191     AddStep(&WrtClient::launchStep);
192     AddStep(&WrtClient::shutdownStep);
193
194     m_initializing = true;
195
196     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
197 }
198
199 void WrtClient::setSdkLauncherDebugData()
200 {
201     LogDebug("setSdkLauncherDebugData");
202
203     /* check bundle from sdk launcher */
204     bundle *bundleFromSdkLauncher;
205     bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
206     const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
207     const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
208     if (bundle_debug != NULL && bundle_pid != NULL) {
209         if (strcmp(bundle_debug, "true") == 0) {
210             m_debugMode = true;
211             m_sdkLauncherPid = atoi(bundle_pid);
212         } else {
213             m_debugMode = false;
214         }
215     }
216 }
217
218 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
219 {
220     LogDebug("Executing next step");
221     NextStep();
222 }
223
224 void WrtClient::initStep()
225 {
226     LogDebug("");
227     if (WRT::CoreModule::Init()) {
228         m_initialized = true;
229     } else {
230         m_returnStatus = ReturnStatus::Failed;
231         SwitchToStep(&WrtClient::shutdownStep);
232     }
233     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
234             NextStepEvent());
235 }
236
237 void WrtClient::LaunchCallback(bool success, void *data) {
238     WrtClient* wrtClient = static_cast<WrtClient*>(data);
239     if (success) {
240         LogDebug("Launch succesfull");
241
242         wrtClient->m_launched = true;
243         wrtClient->m_initializing = false;
244         setlinebuf(stdout);
245         printf("launched\n");
246         fflush(stdout);
247     } else {
248         LogError("Launch unsuccesfull");
249
250         printf("failed\n");
251
252         wrtClient->m_returnStatus = ReturnStatus::Failed;
253         //shutdownStep
254         wrtClient->DPL::Event::ControllerEventHandler<NextStepEvent>::
255                 PostEvent(NextStepEvent());
256     }
257     ApplicationDataSingleton::Instance().freeBundle();
258 }
259
260 void WrtClient::launchStep()
261 {
262     LogDebug("Launching widget ...");
263
264     m_widget = WRT::CoreModule::getRunnableWidgetObject(m_handle);
265     if (!m_widget) {
266         LogError("RunnableWidgetObject is NULL, stop launchStep");
267         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
268                     NextStepEvent());
269         return;
270     }
271
272     if (m_widgetState == WidgetState_Running) {
273         LogWarning("Widget already running, stop launchStep");
274         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
275                     NextStepEvent());
276         return;
277     }
278
279     if (m_widgetState == WidgetState_Authorizing) {
280         LogWarning("Widget already authorizing, stop launchStep");
281         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
282                     NextStepEvent());
283         return;
284     }
285
286     m_widgetState = WidgetState_Authorizing;
287     if (!m_widget->CheckBeforeLaunch()) {
288         LogError("CheckBeforeLaunch failed, stop launchStep");
289         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
290                     NextStepEvent());
291         return;
292     }
293     LogInfo("Widget launch accepted. Entering running state");
294     m_widgetState = WidgetState_Running;
295     m_widget->PrepareView();
296     m_widget->SetDebugMode(m_debugMode, m_sdkLauncherPid);
297     WRT::FinishedCallback callback;
298     callback.callback = &LaunchCallback;
299     callback.userData = this;
300     m_widget->Show(callback);
301 }
302
303 void WrtClient::shutdownStep()
304 {
305     LogDebug("Closing Wrt connection ...");
306     if (m_initialized && m_widget) {
307         m_widgetState = WidgetState_Stopped;
308         m_widget->Hide();
309         m_widget.reset();
310         WRT::CoreModule::Terminate();
311         m_initialized = false;
312     }
313     Quit();
314 }
315
316 int main(int argc,
317          char *argv[])
318 {
319     ADD_PROFILING_POINT("main-entered", "point");
320
321     // Output on stdout will be flushed after every newline character,
322     // even if it is redirected to a pipe. This is useful for running
323     // from a script and parsing output.
324     // (Standard behavior of stdlib is to use full buffering when
325     // redirected to a pipe, which means even after an end of line
326     // the output may not be flushed).
327     setlinebuf(stdout);
328
329     // set evas backend type
330     if (!getenv("ELM_ENGINE")) {
331         if (setenv("ELM_ENGINE", "gl", 1)) {
332                 LogDebug("Enable backend");
333         }
334     }
335     setenv("COREGL_FASTPATH", "1", 1);
336     // Set log tagging
337     DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT");
338
339     WrtClient app(argc, argv);
340     int ret = app.Exec();
341     LogDebug("App returned: " << ret);
342     ret = app.getReturnStatus();
343     LogDebug("WrtClient returned: " << ret);
344     return ret;
345 }