8aa67b77db08577ce31176ef07800958b7309ef0
[platform/framework/web/crosswalk.git] / src / xwalk / application / tools / linux / xwalk_launcher_tizen.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "xwalk/application/tools/linux/xwalk_launcher_tizen.h"
7
8 #include <unistd.h>
9 #include <pkgmgr-info.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include <string>
15
16 #include "base/logging.h"
17 #include "url/gurl.h"
18
19 // Private struct from appcore-internal, necessary to get events from
20 // the system.
21 struct ui_ops {
22   void* data;
23   void (*cb_app)(app_event evnt, void* data, bundle* b);
24 };
25
26 namespace {
27
28 const char* Event2Str(app_event event) {
29   switch (event) {
30     case AE_UNKNOWN:
31       return "AE_UNKNOWN";
32     case AE_CREATE:
33       return "AE_CREATE";
34     case AE_TERMINATE:
35       return "AE_TERMINATE";
36     case AE_PAUSE:
37       return "AE_PAUSE";
38     case AE_RESUME:
39       return "AE_RESUME";
40     case AE_RESET:
41       return "AE_RESET";
42     case AE_LOWMEM_POST:
43       return "AE_LOWMEM_POST";
44     case AE_MEM_FLUSH:
45       return "AE_MEM_FLUSH";
46     case AE_MAX:
47       return "AE_MAX";
48   }
49
50   return "INVALID EVENT";
51 }
52
53 ui_ops app_ops;
54
55 }  // namespace
56
57 XWalkLauncherTizen::XWalkLauncherTizen(bool query_running,
58     base::MessageLoop* main_loop)
59     : XWalkLauncher(query_running, main_loop) {
60 }
61
62 int XWalkLauncherTizen::Launch(const std::string& appid_or_url, bool fullscreen,
63                                bool remote_debugging, int argc, char* argv[]) {
64   appid_or_url_ = appid_or_url;
65   fullscreen_ = fullscreen;
66   remote_debugging_ = remote_debugging;
67   // Query app.
68   if (query_running_) {
69     return dbus_object_manager_->IsApplicationRunning(appid_or_url_);
70   }
71   std::string name = "xwalk-" + appid_or_url_;
72
73   if (XwalkAppcoreInit(name, argc, argv)) {
74     LOG(ERROR) << "Failed to initialize appcore.";
75     return 1;
76   }
77   if (GURL(appid_or_url_).spec().empty()
78       && XwalkChangeCmdline(appid_or_url_, argc, argv))
79     return 1;
80   return 0;
81 }
82
83 bool XWalkLauncherTizen::Suspend() {
84   return dbus_object_manager_->Suspend();
85 }
86
87 bool XWalkLauncherTizen::Resume() {
88   return dbus_object_manager_->Resume();
89 }
90
91 void XWalkLauncherTizen::application_event_cb(app_event event,
92                                               void* data, bundle* b) {
93   XWalkLauncherTizen* xwalk_launcher = static_cast<XWalkLauncherTizen*>(data);
94   LOG(INFO) << "event '" << Event2Str(event) << "'";
95
96   switch (event) {
97     case AE_UNKNOWN:
98     case AE_CREATE:
99       break;
100     case AE_TERMINATE:
101       xwalk_launcher->main_loop_->QuitNow();
102       break;
103     case AE_PAUSE:
104       if (!xwalk_launcher->Suspend())
105         LOG(ERROR) << "Suspending application failed";
106       break;
107     case AE_RESUME:
108       if (!xwalk_launcher->Resume())
109         LOG(ERROR) << "Resuming application failed";
110       break;
111     case AE_RESET:
112       if (!xwalk_launcher->LaunchApplication())
113         xwalk_launcher->main_loop_->QuitNow();
114       break;
115     case AE_LOWMEM_POST:
116     case AE_MEM_FLUSH:
117     case AE_MAX:
118       break;
119   }
120 }
121
122 int XWalkLauncherTizen::XwalkAppcoreInit(const std::string& name,
123                                          int argc, char* argv[]) {
124   app_ops.cb_app = application_event_cb;
125   app_ops.data = this;
126   return appcore_init(name.c_str(), &app_ops, argc, argv);
127 }
128
129 int XWalkLauncherTizen::XwalkChangeCmdline(const std::string& app_id,
130                                            int argc, char* argv[]) {
131   // Change /proc/<pid>/cmdline to app exec path. See XWALK-1722 for details.
132   pkgmgrinfo_appinfo_h handle;
133   char* exec_path = nullptr;
134   // todo : add is_admin
135   if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(),
136       getuid(), &handle) != PMINFO_R_OK ||
137       pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
138       !exec_path) {
139     if (pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle) !=
140         PMINFO_R_OK ||
141         pkgmgrinfo_appinfo_get_exec(handle, &exec_path) != PMINFO_R_OK ||
142         !exec_path) {
143       LOG(ERROR) << "Couldn't find exec path for application: " << app_id;
144       return -1;
145     }
146   }
147
148   // zeros g_argv_
149   for (int i = 0; i < argc; ++i)
150     memset(argv[i], 0, strlen(argv[i]));
151
152   strncpy(argv[0], exec_path, strlen(exec_path) + 1);
153   pkgmgrinfo_appinfo_destroy_appinfo(handle);
154   return 0;
155 }