2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "wrt-client.h"
20 #include <dpl/log/log.h>
21 #include <dpl/optional_typedefs.h>
22 #include <common/application_data.h>
23 #include <core_module.h>
24 #include <global_logic.h>
25 #include <widget_localize_model.h>
27 WrtClient::WrtClient(int argc, char **argv) :
28 Application(argc, argv, "wrt-client", false),
29 DPL::TaskDecl<WrtClient>(this),
32 m_initializing(false),
37 m_returnStatus(ReturnStatus::Succeeded),
38 m_widgetState(WidgetState::WidgetState_Stopped)
41 LogDebug("App Created");
44 WrtClient::~WrtClient()
46 LogDebug("App Finished");
49 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
51 return m_returnStatus;
54 void WrtClient::OnStop()
56 LogInfo("Stopping Dummy Client");
60 void WrtClient::OnCreate()
66 void WrtClient::OnResume()
68 if (m_widgetState != WidgetState_Suspended) {
69 LogWarning("Widget is not suspended, resuming was skipped");
73 m_widgetState = WidgetState_Running;
77 void WrtClient::OnPause()
79 if (m_widgetState != WidgetState_Running) {
80 LogWarning("Widget is not running to be suspended");
84 m_widgetState = WidgetState_Suspended;
87 void WrtClient::OnReset(bundle *b)
90 // bundle argument is freed after OnReset() is returned
91 // So bundle duplication is needed
92 ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
94 if (true == m_initializing) {
95 LogDebug("can not handle reset event");
98 if (true == m_launched) {
99 if (m_widgetState == WidgetState_Stopped) {
100 LogError("Widget is not running to be reset");
104 m_widgetState = WidgetState_Running;
106 if (true == checkArgument())
117 void WrtClient::OnTerminate()
119 LogDebug("Wrt Shutdown now");
123 void WrtClient::showHelpAndQuit()
125 printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
127 "Mandatory arguments to long options are mandatory for short "
129 " -h, --help show this help\n"
131 "launch widget with given ID\n"
137 bool WrtClient::checkArgument()
139 LogInfo("checkArgument");
141 std::string arg = m_argv[0];
147 if (arg.find("wrt-client") != std::string::npos)
155 if (arg == "-h" || arg == "--help") {
158 } else if (arg == "-l" || arg == "--launch") {
162 m_handle = atoi(m_argv[2]);
167 size_t pos = arg.find_last_of('/');
169 if (pos != std::string::npos) {
170 arg = arg.erase(0, pos + 1);
173 // Launch widget based on application basename
174 if (sscanf(arg.c_str(), "%i", &m_handle) != 1) {
175 printf("failed: invalid widget handle\n");
179 LogDebug("Widget Id: " << m_handle << " (" << arg << ")");
185 void WrtClient::setStep()
189 AddStep(&WrtClient::initStep);
191 setSdkLauncherDebugData();
193 AddStep(&WrtClient::launchStep);
194 AddStep(&WrtClient::shutdownStep);
196 m_initializing = true;
198 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
201 void WrtClient::setSdkLauncherDebugData()
203 LogDebug("setSdkLauncherDebugData");
205 /* check bundle from sdk launcher */
206 bundle *bundleFromSdkLauncher;
207 bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
208 const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
209 const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
210 if (bundle_debug != NULL && bundle_pid != NULL) {
211 if (strcmp(bundle_debug, "true") == 0) {
213 m_sdkLauncherPid = atoi(bundle_pid);
220 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
222 LogDebug("Executing next step");
226 void WrtClient::initStep()
229 if (WRT::CoreModuleSingleton::Instance().Init()) {
230 m_initialized = true;
232 m_returnStatus = ReturnStatus::Failed;
233 SwitchToStep(&WrtClient::shutdownStep);
235 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
239 void WrtClient::localizeWidgetModel() {
241 WRT::WidgetModelPtr model = m_widget->GetModel();
243 Domain::localizeWidgetModel(model);
244 model->RunningName.Set(model->Name.Get());
245 model->RunningIcon.Set(model->Icon.Get());
246 model->RunningStartURL.Set(model->StartURL.Get());
247 model->RunningShortName.Set(model->ShortName.Get());
248 model->RunningDescription.Set(model->Description.Get());
249 model->RunningLicense.Set(model->License.Get());
250 model->RunningLicenseHref.Set(model->LicenseHref.Get());
251 model->RunningStartFileInfo.Set(
252 model->StartFileInfo.Get());
255 bool WrtClient::checkWACTestCertififedWidget()
257 // WAC Waikiki Beta Release Core Specification: Widget Runtime
260 // WR-4710 The WRT MUST enable debug functions only for WAC test widgets
261 // i.e. the functions must not be usable for normal WAC widgets, even when
262 // a WAC test widget is executing.
263 ADD_PROFILING_POINT("DeveloperModeCheck", "start");
265 WRT::WidgetModelPtr model = m_widget->GetModel();
268 // A widget signed with a WAC-issued test certificate as described in
271 bool developerWidget = model->IsTestWidget.Get();
273 GlobalLogicSingleton::Instance().GetGlobalModel()->DeveloperMode.Get();
275 LogDebug("Is WAC test widget: " << developerWidget);
276 LogDebug("Is developer Mode: " << developerMode);
278 if (developerWidget) {
281 LogError("WAC test certified developer widget is needed for " <<
285 //TODO: WR-4660 (show popup about developer widget
287 LogInfo("POPUP: THIS IS TEST WIDGET!");
290 ADD_PROFILING_POINT("DeveloperModeCheck", "stop");
294 void WrtClient::staticWrtLaunchWidgetCallback(int /*handle*/,
295 CommonError::Type status,
296 const std::string& errorMsg,
299 WrtLaunchData* userData = static_cast<WrtLaunchData*>(userdata);
300 WrtClient* wrtClient = static_cast<WrtClient*>(userData->wrtClientContext);
301 SDKDebugData* debug = userData->sdkDebugData;
303 if (status == CommonError::WrtSuccess) {
304 LogDebug("Launch succesfull");
306 wrtClient->m_launched = true;
307 wrtClient->m_initializing = false;
309 printf("launched\n");
312 LogError("Launch unsuccesfull: " << errorMsg);
316 wrtClient->m_returnStatus = ReturnStatus::Failed;
318 wrtClient->DPL::Event::ControllerEventHandler<NextStepEvent>::
319 PostEvent(NextStepEvent());
324 LogDebug("Send RT signal to wrt-launcher(pid: "
325 << wrtClient->m_sdkLauncherPid << ", status: " << status);
327 /* send real time signal with result to wrt-launcher */
328 if(status == CommonError::WrtSuccess)
330 LogDebug("userData->portnum : " << debug->portnum);
331 sv.sival_int = debug->portnum;
337 sigqueue(wrtClient->m_sdkLauncherPid, SIGRTMIN, sv);
340 ApplicationDataSingleton::Instance().freeBundle();
342 LogDebug("Cleaning wrtClient launch resources...");
348 void WrtClient::launchStep()
350 LogDebug("Launching widget ...");
352 m_widget = WRT::CoreModuleSingleton::Instance().getRunnableWidgetObject(m_handle);
354 LogError("RunnableWidgetObject is NULL, stop launchStep");
355 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
360 if (m_widgetState == WidgetState_Running) {
361 LogWarning("Widget already running, stop launchStep");
362 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
367 if (m_widgetState == WidgetState_Authorizing) {
368 LogWarning("Widget already authorizing, stop launchStep");
369 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
374 // Widget is not running, localized data can be updated
375 localizeWidgetModel();
377 if (!checkWACTestCertififedWidget())
379 LogWarning("WAC Certificate failed, stop launchStep");
383 m_widgetState = WidgetState_Authorizing;
384 if (!m_widget->CheckBeforeLaunch()) {
385 LogError("CheckBeforeLaunch failed, stop launchStep");
386 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
390 LogInfo("Widget launch accepted. Entering running state");
391 m_widgetState = WidgetState_Running;
392 m_widget->PrepareView();
393 SDKDebugData* debugData = new SDKDebugData;
394 debugData->debugMode = m_debugMode;
395 debugData->pid = new unsigned long(getpid());
396 WrtLaunchData* userData = new WrtLaunchData;
397 userData->wrtClientContext = this;
398 userData->sdkDebugData = debugData;
399 WidgetLaunchStruct launch(
401 &staticWrtLaunchWidgetCallback,
405 m_widget->Show(launch);
408 void WrtClient::shutdownStep()
410 LogDebug("Closing Wrt connection ...");
411 if (m_initialized && m_widget) {
412 m_widgetState = WidgetState_Stopped;
415 WRT::CoreModuleSingleton::Instance().Terminate();
416 m_initialized = false;
424 ADD_PROFILING_POINT("main-entered", "point");
426 // Output on stdout will be flushed after every newline character,
427 // even if it is redirected to a pipe. This is useful for running
428 // from a script and parsing output.
429 // (Standard behavior of stdlib is to use full buffering when
430 // redirected to a pipe, which means even after an end of line
431 // the output may not be flushed).
434 // set evas backend type
435 if (!getenv("ELM_ENGINE")) {
436 if (setenv("ELM_ENGINE", "gl", 1)) {
437 LogDebug("Enable backend");
440 setenv("COREGL_FASTPATH", "1", 1);
442 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT");
444 WrtClient app(argc, argv);
445 int ret = app.Exec();
446 LogDebug("App returned: " << ret);
447 ret = app.getReturnStatus();
448 LogDebug("WrtClient returned: " << ret);