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"
22 #include <sys/utsname.h>
25 #include <dpl/optional.h>
26 #include <dpl/scoped_free.h>
27 #include <dpl/wrt-dao-ro/global_config.h>
28 #include <dpl/localization/localization_utils.h>
29 #include <dpl/optional_typedefs.h>
30 #include <dpl/semaphore.h>
31 #include <dpl/exception.h>
33 #include <application_data.h>
34 #include <window_data.h>
36 using namespace WrtDB;
38 namespace { // anonymous
39 const char* PLUGIN_INSTALL_SEMAPHORE = "/.wrt_plugin_install_lock";
40 const char* MACHINE_NAME_EMUL = "emulated"; // "arch_emulated"
42 template<typename Predicate>
43 DPL::OptionalInt findWidgetHandleForPredicate(const Predicate &predicate)
48 if (wrt_has_succeded(wrt_get_widget_list(&count, &handles))) {
49 for (int i = 0; i < count; ++i) {
50 wrt_widget_info *info;
52 // Get widget infor for handle
53 if (wrt_has_succeded(wrt_get_widget_info(handles[i], &info))) {
54 if (predicate(info)) {
56 wrt_free_widget_info(info);
59 return DPL::OptionalInt(handles[i]);
63 wrt_free_widget_info(info);
65 LogWarning("ReturnStatus::Faileded to get widget name");
70 wrt_free_widget_list(handles);
72 LogWarning("ReturnStatus::Faileded to get widget handle list");
75 return DPL::OptionalInt::Null;
78 struct WidgetNamePredicate
84 WidgetNamePredicate(const std::string &name) : m_name(name) {}
86 bool operator()(wrt_widget_info *info) const
88 return info->name && m_name == info->name;
92 struct WidgetGUIDPredicate
98 WidgetGUIDPredicate(const std::string &guid) : m_guid(guid) {}
100 bool operator()(wrt_widget_info *info) const
102 return info->id && m_guid == info->id;
106 DPL::OptionalInt findWidgetHandleForName(const std::string &widgetName)
108 return findWidgetHandleForPredicate(WidgetNamePredicate(widgetName));
111 DPL::OptionalInt findWidgetHandleForGUID(const std::string &widgetName)
113 return findWidgetHandleForPredicate(WidgetGUIDPredicate(widgetName));
116 struct PluginInstallerData
119 std::string pluginPath;
129 FILE_EXISTS_NOT_REGULAR,
135 static bool lockPluginInstallation()
138 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
141 Catch(DPL::Semaphore::Exception::CreateFailed){
145 Catch(DPL::Semaphore::Exception::Base){
150 static bool unlockPluginInstallation()
153 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
156 Catch(DPL::Semaphore::Exception::Base){
161 static bool checkPluginInstallationRequired()
163 std::string installRequest =
164 std::string(GlobalConfig::GetPluginInstallInitializerName());
166 FileState::Type installationRequest = checkFile(installRequest);
168 switch (installationRequest) {
169 case FileState::FILE_EXISTS:
171 case FileState::FILE_NOT_EXISTS:
174 LogWarning("Opening installation request file failed");
179 static bool removeInstallationRequiredFlag()
181 std::string installRequest =
182 std::string(GlobalConfig::GetPluginInstallInitializerName());
184 return removeFile(installRequest);
187 //checks if file exists and is regular file
188 static FileState::Type checkFile(const std::string& filename)
192 if (-1 == stat(filename.c_str(), &tmp)) {
193 if (ENOENT == errno) {
194 return FileState::FILE_NOT_EXISTS;
196 return FileState::FILE_READ_DATA_ERROR;
197 } else if (!S_ISREG(tmp.st_mode)) {
198 return FileState::FILE_EXISTS_NOT_REGULAR;
200 return FileState::FILE_EXISTS;
203 static bool removeFile(const std::string& filename)
205 if (0 != unlink(filename.c_str())) {
212 } // namespace anonymous
214 WrtClient::WrtClient(int argc, char **argv) :
215 Application(argc, argv, "wrt-client", false),
216 DPL::TaskDecl<WrtClient>(this),
220 m_initialized(false),
224 m_developerMode(false),
225 m_complianceMode(false),
226 m_numPluginsToInstall(0),
227 m_returnStatus(ReturnStatus::Succeeded),
228 m_startupPluginInstallation(false)
231 LogDebug("App Created");
234 WrtClient::~WrtClient()
236 LogDebug("App Finished");
239 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
241 return m_returnStatus;
244 void WrtClient::OnStop()
246 LogInfo("Stopping Dummy Client");
250 void WrtClient::OnCreate()
252 LogInfo("On Create");
256 void WrtClient::OnResume()
258 wrt_resume_widget(m_handle, NULL, staticWrtResumeStatusCallback);
262 void WrtClient::OnPause()
264 wrt_suspend_widget(m_handle, NULL, staticWrtSuspendStatusCallback);
267 void WrtClient::OnReset(bundle *b)
270 // bundle argument is freed after OnReset() is returned
271 // So bundle duplication is needed
272 ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
274 if (m_launched == true) {
275 wrt_reset_widget(m_handle, NULL, staticWrtResetStatusCallback);
281 void WrtClient::OnTerminate()
283 LogDebug("Wrt Shutdown now");
287 void WrtClient::showHelpAndQuit()
289 printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
291 "Mandatory arguments to long options are mandatory for short "
293 " -h, --help show this help\n"
295 "launch widget with given ID\n"
301 void WrtClient::setStep()
305 AddStep(&WrtClient::initStep);
307 std::string arg = m_argv[0];
310 return showHelpAndQuit();
315 setSdkLauncherDebugData();
317 if (arg.find("wrt-dummy-client") != std::string::npos ||
318 arg.find("wrt-client") != std::string::npos)
321 return showHelpAndQuit();
326 if (arg == "-h" || arg == "--help") {
328 return showHelpAndQuit();
333 } else if (arg == "-l" || arg == "--launch") {
335 return showHelpAndQuit();
338 m_handle = atoi(m_argv[2]);
339 AddStep(&WrtClient::launchStep);
340 AddStep(&WrtClient::finalizeLaunchStep);
341 AddStep(&WrtClient::killWidgetStep);
343 return showHelpAndQuit();
346 // Launch widget based on application basename
347 size_t pos = arg.find_last_of('/');
349 if (pos != std::string::npos) {
350 arg = arg.erase(0, pos + 1);
353 if (sscanf(arg.c_str(), "%i", &m_handle) != 1) {
354 printf("failed: invalid widget handle\n");
355 return showHelpAndQuit();
358 LogDebug("Widget Id: " << m_handle << " (" << arg << ")");
360 AddStep(&WrtClient::launchStep);
361 AddStep(&WrtClient::finalizeLaunchStep);
362 AddStep(&WrtClient::killWidgetStep);
365 AddStep(&WrtClient::shutdownStep);
367 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
370 void WrtClient::setSdkLauncherDebugData()
372 LogDebug("setSdkLauncherDebugData");
374 /* check bundle from sdk launcher */
375 bundle *bundleFromSdkLauncher;
376 bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
377 const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
378 const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
379 if (bundle_debug != NULL && bundle_pid != NULL) {
380 if (strcmp(bundle_debug, "true") == 0) {
382 m_sdkLauncherPid = atoi(bundle_pid);
389 void WrtClient::OnEventReceived(const QuitEvent &/* event */)
394 LogDebug("Killing widgets first");
395 SwitchToStep(&WrtClient::killWidgetStep);
396 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
397 } else if (m_initialized) {
398 LogDebug("Wrt Shutdown now");
399 SwitchToStep(&WrtClient::shutdownStep);
400 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
402 LogDebug("Quiting application");
407 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
409 LogDebug("Executing next step");
413 void WrtClient::initStep()
415 wrt_init(this, staticWrtInitCallback);
418 void WrtClient::launchStep()
420 LogDebug("Launching widget ...");
422 WrtClientUserData *userData = new WrtClientUserData;
423 userData->This = this;
424 userData->pid = new unsigned long(getpid());
425 userData->debugMode = this->m_debugMode;
427 wrt_launch_widget(m_handle,
431 &staticWrtLaunchWidgetCallback);
434 void WrtClient::launchNameStep()
436 LogDebug("Launching name widget ...");
438 DPL::OptionalInt handle = findWidgetHandleForName(m_name);
441 printf("failed: widget name not found\n");
443 m_returnStatus = ReturnStatus::Failed;
444 DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
448 WrtClientUserData *userData = new WrtClientUserData;
449 userData->This = this;
450 userData->pid = new unsigned long(getpid());
451 userData->debugMode = this->m_debugMode;
453 wrt_launch_widget(*handle,
457 &staticWrtLaunchWidgetCallback);
460 void WrtClient::launchGUIDStep()
462 LogDebug("Launching GUID widget ...");
464 DPL::OptionalInt handle = findWidgetHandleForGUID(m_name);
467 printf("failed: widget GUID not found\n");
469 m_returnStatus = ReturnStatus::Failed;
470 DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
474 WrtClientUserData *userData = new WrtClientUserData;
475 userData->This = this;
476 userData->pid = new unsigned long(getpid());
477 userData->debugMode = this->m_debugMode;
479 wrt_launch_widget(*handle,
483 &staticWrtLaunchWidgetCallback);
486 void WrtClient::killWidgetStep()
488 LogDebug("Killing widget ...");
489 wrt_kill_widget(m_handle, this, &staticWrtStatusCallback);
492 void WrtClient::finalizeLaunchStep()
494 LogDebug("Finalizing Launching widget ...");
498 void WrtClient::shutdownStep()
500 LogDebug("Closing Wrt connection ...");
502 m_initialized = false;
503 DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
506 void WrtClient::setDeveloperModeStep()
508 LogDebug("Set developer mode...");
509 wrt_set_developer_mode(m_developerMode,
510 &staticSetDeveloperModeCallback,
514 void WrtClient::setComplianceModeStep()
516 LogDebug("Set compliance mode...");
517 wrt_set_compliance_mode(m_complianceMode,
518 &staticSetComplianceModeCallback,
522 void WrtClient::setComplianceImeiStep()
524 LogDebug("Set compliance fake IMEI...");
525 wrt_set_compliance_fake_imei(m_complianceIMEI.c_str(),
526 &staticSetComplianceImeiCallback,
530 void WrtClient::setComplianceMeidStep()
532 LogDebug("Set compliance fake MEID...");
533 wrt_set_compliance_fake_meid(m_complianceMEID.c_str(),
534 &staticSetComplianceMeidCallback,
538 void WrtClient::queryListStep()
540 LogDebug("Query list...");
545 printf("%3s%12s%32s%16s%64s%32s\n",
546 "No", "ID", "Name", "Version", "GUID", "Package Name");
547 printf("%3s%12s%32s%16s%64s%32s\n",
548 "--", "--", "----", "-------", "----", "------------");
550 if (wrt_has_succeded(wrt_get_widget_list(&count, &handles))) {
551 for (int i = 0; i < count; ++i) {
552 wrt_widget_info *info;
554 // Get widget infor for handle
555 WrtErrStatus status = wrt_get_widget_info(handles[i], &info);
556 LogInfo("Status: " << status);
557 if (wrt_has_succeded(status)) {
558 printf("%3i%12i%32s%16s%64s%32s\n",
561 !info->name ? "[NULL]" : info->name,
562 !info->version ? "[NULL]" : info->version,
563 !info->id ? "[NULL]" : info->id,
564 !info->pkg_name ? "[NULL]" : info->pkg_name);
567 wrt_free_widget_info(info);
569 LogWarning("ReturnStatus::Failed to get widget name");
574 wrt_free_widget_list(handles);
576 LogWarning("ReturnStatus::Failed to get widget handle list");
579 DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
582 void WrtClient::staticWrtInitCallback(WrtErrStatus status,
585 WrtClient *This = static_cast<WrtClient*>(userdata);
587 if (status == WRT_SUCCESS) {
588 LogDebug("Init succesfull");
589 This->m_initialized = true;
590 This->DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
593 LogError("Init unsuccesfull");
594 This->m_returnStatus = ReturnStatus::Failed;
595 This->DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
599 void WrtClient::staticWrtLaunchWidgetCallback(void* /*canvas*/,
602 const char* errorMsg,
605 WrtClientUserData *userData = static_cast<WrtClientUserData*>(userdata);
607 if (status == WRT_SUCCESS) {
608 LogDebug("Launch succesfull");
610 userData->This->m_handle = handle;
611 userData->This->DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
615 printf("launched\n");
618 LogError("Launch unsuccesfull: " << errorMsg);
622 userData->This->m_returnStatus = ReturnStatus::Failed;
623 userData->This->DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(
627 if(userData->debugMode == EINA_TRUE)
629 LogDebug("Send RT signal to wrt-launcher(pid: "
630 << userData->This->m_sdkLauncherPid << ", status: " << status);
632 /* send real time signal with result to wrt-launcher */
633 if(status == WRT_SUCCESS)
635 LogDebug("userData->portnum : " << userData->portnum);
636 sv.sival_int = userData->portnum;
642 sigqueue(userData->This->m_sdkLauncherPid, SIGRTMIN, sv);
645 ApplicationDataSingleton::Instance().freeBundle();
647 delete userData->pid;
651 void WrtClient::staticWrtStatusCallback(int handle,
655 WrtClient *This = static_cast<WrtClient*>(userdata);
657 if (status == WRT_SUCCESS) {
658 LogDebug("Status succesfull");
659 This->m_handle = handle;
660 This->m_launched = false;
662 This->DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
669 LogWarning("Install failed!");
671 This->m_returnStatus = ReturnStatus::Failed;
672 This->DPL::Event::ControllerEventHandler<QuitEvent>::PostEvent(QuitEvent());
675 void WrtClient::staticCloseWidgetCallback(int /*widgetHandle*/,
678 WrtClient *This = static_cast<WrtClient*>(data);
680 This->DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
684 void WrtClient::staticSetDeveloperModeCallback(void *userParam)
686 WrtClient *This = static_cast<WrtClient *>(userParam);
688 This->DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
692 void WrtClient::staticSetComplianceModeCallback(void *userParam)
695 WrtClient *This = static_cast<WrtClient *>(userParam);
697 LogInfo("Compliance mode is " <<
698 (This->m_complianceMode ? "enabled" : "disabled"));
700 This->DPL::Event::ControllerEventHandler<NextStepEvent>::
701 PostEvent(NextStepEvent());
704 void WrtClient::staticSetComplianceImeiCallback(void *userParam)
707 WrtClient *This = static_cast<WrtClient *>(userParam);
709 LogInfo("Compliance fake IMEI is " << This->m_complianceIMEI);
711 This->DPL::Event::ControllerEventHandler<NextStepEvent>::
712 PostEvent(NextStepEvent());
715 void WrtClient::staticSetComplianceMeidCallback(void *userParam)
718 WrtClient *This = static_cast<WrtClient *>(userParam);
720 LogInfo("Compliance fake MEID is " << This->m_complianceMEID);
722 This->DPL::Event::ControllerEventHandler<NextStepEvent>::
723 PostEvent(NextStepEvent());
726 void WrtClient::staticWrtResumeStatusCallback(int /*handle*/,
730 if (WRT_SUCCESS == status) {
731 LogDebug("Resume succesfull");
736 void WrtClient::staticWrtSuspendStatusCallback(int /*handle*/,
740 if (WRT_SUCCESS == status) {
741 LogDebug("Suspend succesfull");
746 void WrtClient::staticWrtResetStatusCallback(int /*handle*/,
750 if (WRT_SUCCESS == status) {
751 LogDebug("Reset succesfull");
756 void WrtClient::installNewPlugins()
758 LogDebug("Install new plugins");
760 if (!PluginUtils::checkPluginInstallationRequired()) {
761 LogDebug("Plugin installation not required");
765 m_startupPluginInstallation = true;
766 system("wrt-installer -p");
772 ADD_PROFILING_POINT("main-entered", "point");
774 // Output on stdout will be flushed after every newline character,
775 // even if it is redirected to a pipe. This is useful for running
776 // from a script and parsing output.
777 // (Standard behavior of stdlib is to use full buffering when
778 // redirected to a pipe, which means even after an end of line
779 // the output may not be flushed).
782 // set evas backend type
783 // check current machine is target or emul
785 std::string backend = "gl";
786 if (0 == uname(&u)) {
787 if ((!u.machine) || (0 == strlen(u.machine))) {
788 LogError("Fail to get machine name");
790 // If current machine is emul,
791 // machine name include "<arch>_emulated"
792 std::string machine = u.machine;
793 LogDebug("machine name is [" << machine << "]");
794 // find "emulated" string in the u.machine
795 if (std::string::npos != machine.find(MACHINE_NAME_EMUL)) {
796 LogDebug("Current machine is emul");
799 //webkit accel needs to evas backend
800 LogDebug("Set backend to gl");
805 perror("Fail to get machine name");
808 if (!getenv("ELM_ENGINE")) {
809 if (setenv("ELM_ENGINE", backend.c_str(), 1)) {
810 LogDebug("Enable backend");
813 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT");
814 WrtClient app(argc, argv);
815 int ret = app.Exec();
816 LogDebug("App returned: " << ret);
817 ret = app.getReturnStatus();
818 LogDebug("WrtClient returned: " << ret);