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.
19 #include <app_manager.h>
26 #include <sys/types.h>
27 #include <dpl/wrt-dao-ro/WrtDatabase.h>
28 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
29 #include <dpl/wrt-dao-ro/feature_dao_read_only.h>
30 #include <dpl/wrt-dao-ro/common_dao_types.h>
31 #include <dpl/wrt-dao-ro/wrt_db_types.h>
32 #include <dpl/wrt-dao-rw/global_dao.h>
33 #include <dpl/wrt-dao-ro/global_dao_read_only.h>
34 #include <dpl/wrt-dao-ro/config_parser_data.h>
35 #include <dpl/exception.h>
38 #define TIMEOUT_DEFAULT 10
39 #define ROOT_DEFAULT_UID 0
40 #define ROOT_DEFAULT_GID 0
41 #define WEBAPP_DEFAULT_UID 5000
42 #define WEBAPP_DEFAULT_GID 5000
43 #define LOGGING_DEFAULT_GID 6509
44 #define RETURN_ERROR -1
46 static const char *program;
53 WrtDB::WrtDatabase::attachToThreadRW();
58 WrtDB::WrtDatabase::detachFromThread();
62 static std::unique_ptr<DBConnection> g_dbConnection;
66 char* guid; /**< the widget's id
67 * (read from its config.xml during installation)*/
68 char* name; /**< the widget's name
69 * (read from its config.xml during installation)*/
70 char* version; /**< the widget's varsion
71 * (read from its config.xml during installation)*/
72 char* pkg_id; /**< the widget's pkg id */
77 static void free_widget_info(widget_info* widget_info)
80 delete[] widget_info->guid;
81 delete[] widget_info->name;
82 delete[] widget_info->version;
83 delete[] widget_info->pkg_id;
84 delete[] widget_info->app_id;
89 static char* new_strdup(const char *str)
91 size_t size = strlen(str);
92 char* ret = new char[size + 1];
97 static bool attachDbConnection()
99 if (NULL == g_dbConnection.get()) {
101 g_dbConnection.reset(new DBConnection());
102 g_dbConnection->AttachDatabase();
104 Catch(DPL::DB::SqlConnection::Exception::Base) {
105 LogDebug("Fail to connect DB");
112 static bool display_widget_info()
114 if (!attachDbConnection()) {
118 WidgetDAOReadOnlyList widgetList =
119 WrtDB::WidgetDAOReadOnly::getWidgetList();
121 printf("%3s %32s %16s %64s %16s %24s\n",
122 "No", "Name", "Version", "GUID", "Package ID", "App ID");
123 printf("%3s %32s %16s %64s %16s %24s\n",
124 "--", "--", "----", "-------", "-----", "-----");
127 FOREACH(dao, widgetList) {
128 widget_info *info = new widget_info;
129 memset(info, 0x00, sizeof(widget_info));
131 WrtDB::WidgetGUID guid = (*dao)->getGUID();
132 DPL::Optional<DPL::String> version = (*dao)->getVersion();
133 WrtDB::TizenAppId appid = (*dao)->getTzAppId();
134 WrtDB::TizenPkgId pkgid = (*dao)->getTizenPkgId();
138 DPL::Optional<DPL::String> widget_name;
139 DPL::OptionalString dl = (*dao)->getDefaultlocale();
140 WrtDB::WidgetLocalizedInfo localizedInfo;
142 DPL::String languageTag(L"");
143 localizedInfo = (*dao)->getLocalizedInfo(languageTag);
145 localizedInfo = (*dao)->getLocalizedInfo(*dl);
148 widget_name = localizedInfo.name;
150 /*end get WidgetName*/
151 if (!widget_name.IsNull()) {
152 info->name = new_strdup(DPL::ToUTF8String(*widget_name).c_str());
154 if (!version.IsNull()) {
155 info->version = new_strdup(DPL::ToUTF8String(*version).c_str());
157 std::string installedWidgetVersionString;
158 installedWidgetVersionString = "";
159 info->version = new_strdup(installedWidgetVersionString.c_str());
161 if (!guid.IsNull()) {
162 info->guid = new_strdup(DPL::ToUTF8String(*guid).c_str());
165 info->app_id = new_strdup(DPL::ToUTF8String(appid).c_str());
166 info->pkg_id = new_strdup(DPL::ToUTF8String(pkgid).c_str());
168 printf("%3i %32s %16s %64s %16s %24s\n",
170 !info->name ? "[NULL]" : info->name,
171 !info->version ? "[NULL]" : info->version,
172 !info->guid ? "[NULL]" : info->guid,
173 !info->pkg_id ? "[NULL]" : info->pkg_id,
174 !info->app_id ? "[NULL]" : info->app_id);
176 free_widget_info(info);
182 static void print_help(FILE *stream, int /*exit_code*/)
184 fprintf(stream, "Usage : %s [ ... ]\n", program);
187 " -h --help Display this usage information.\n"
188 " -l --list Display installed widgets list\n"
189 " -s [tizen application ID] --start Launch widget with tizen application ID\n"
190 " -k [tizen application ID] --kill Kill widget with tizen application ID\n"
191 " -r [tizen application ID] --is-running Check whether widget is running by tizen application ID,\n"
192 " If widget is running, 0(zero) will be returned.\n"
193 " -d --debug Activate debug mode\n"
194 " -t [second] --timeout Set timeout of response from widget in debug mode\n"
195 " if you emit this option, 5 seconds is set in debug mode\n"
199 extern "C" int service_to_bundle(service_h service, bundle** data);
201 static void serviceReplyCallback(service_h /*request*/,
203 service_result_e /*result*/,
206 Ecore_Timer* serviceTimer = static_cast<Ecore_Timer*>(data);
207 if (serviceTimer != NULL) {
208 ecore_timer_del(serviceTimer);
212 service_to_bundle(reply, &b);
213 const char* port = appsvc_get_data(b, "port");
214 if (port != NULL && strlen(port) > 0) {
215 printf("port: %s\n", port);
216 printf("result: %s\n", "launched");
218 printf("result: %s\n", "failed");
220 ecore_main_loop_quit();
224 static Eina_Bool timerCallback(void* /*data*/)
226 printf("result: %s\n", "failed");
227 ecore_main_loop_quit();
231 int main(int argc, char* argv[])
233 UNHANDLED_EXCEPTION_HANDLER_BEGIN
235 int next_opt, opt_idx = 0;
236 int timeout = TIMEOUT_DEFAULT;
237 char applicationId[256] = "";
238 char temp_arg[256] = "";
241 bool isDebugMode = false;
242 bool dispHelp = false;
243 bool dispList = false;
244 Ecore_Timer* serviceTimer = NULL;
246 service_h serviceHandle = NULL;
247 int ret = SERVICE_ERROR_NONE;
251 static struct option long_options[] = {
252 { "help", no_argument, 0, 'h' },
253 { "list", no_argument, 0, 'l' },
254 { "start", required_argument, 0, 's' },
255 { "kill", required_argument, 0, 'k' },
256 { "is-running", required_argument, 0, 'r' },
257 { "debug", no_argument, 0, 'd' },
258 { "timeout", required_argument, 0, 't' },
262 if (argv[1] == NULL) {
263 /* exit if any argument doesn't exist */
264 print_help(stdout, 0);
268 if (ROOT_DEFAULT_UID == geteuid()) {
269 if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) {
270 perror("Fail to set uid");
273 if (ROOT_DEFAULT_GID == getegid()) {
274 if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) {
275 perror("Fail to set gid");
280 next_opt = getopt_long(argc,
282 "hls:k:r:dt:v:c:i:m:",
289 print_help(stdout, 0);
298 if (!display_widget_info()) {
299 printf("Fail to display the list of installed widgets");
308 strncpy(temp_arg, optarg, strlen(optarg));
313 timeout = atoi(optarg);
315 timeout = TIMEOUT_DEFAULT;
321 ret = service_create(&serviceHandle);
322 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
323 LogError("Fail to create service");
328 ret = service_add_extra_data(serviceHandle,
331 if (SERVICE_ERROR_NONE != ret) {
332 LogError("Fail to set debug mode [" << ret << "]");
333 service_destroy(serviceHandle);
338 snprintf(pid, sizeof(pid), "%d", getpid());
339 ret = service_add_extra_data(serviceHandle,
342 if (SERVICE_ERROR_NONE != ret) {
343 LogError("Fail to set pid [" << ret << "]");
344 service_destroy(serviceHandle);
354 print_help(stdout, 0);
357 } while (next_opt != -1);
359 if ((op == 's') || (op == 'k') || (op == 'r')) {
362 if (NULL == g_dbConnection.get()) {
364 g_dbConnection.reset(new DBConnection());
365 g_dbConnection->AttachDatabase();
367 Catch(DPL::DB::SqlConnection::Exception::Base) {
368 LogDebug("Fail to connect DB");
372 DPL::OptionalString normal_str = DPL::FromUTF8String(temp_arg);
373 WrtDB::NormalizeAndTrimSpaceString(normal_str);
374 std::string normal_arg = DPL::ToUTF8String(*normal_str);
376 WidgetDAOReadOnlyList widgetList =
377 WrtDB::WidgetDAOReadOnly::getWidgetList();
378 FOREACH(dao, widgetList) {
379 WrtDB::TizenAppId tizenAppId = (*dao)->getTzAppId();
380 if (!strcmp(DPL::ToUTF8String(tizenAppId).c_str(),
383 temp = DPL::ToUTF8String(tizenAppId);
388 strncpy(applicationId, temp.c_str(), strlen(temp.c_str()));
390 printf("result: %s\n", "failed");
396 /* check if this is request for debug mode, or not */
397 if (true != isDebugMode) {
398 // case of "-d" option, service_create is already allocated
400 ret = service_create(&serviceHandle);
401 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
402 printf("result: %s\n", "failed");
407 if (strlen(applicationId) > 0) {
408 // do setuid to '5000' uid to communicate
409 //with webapp using RT signal.
411 group_list[0] = LOGGING_DEFAULT_GID;
413 if (setgroups(sizeof(group_list), group_list) < 0) {
414 printf("result: %s\n", "failed");
418 if (setreuid(WEBAPP_DEFAULT_UID, WEBAPP_DEFAULT_GID) < 0) {
419 printf("result: %s\n", "failed");
424 ret = service_set_package(serviceHandle, applicationId);
425 if (SERVICE_ERROR_NONE != ret) {
426 printf("result: %s\n", "failed");
427 service_destroy(serviceHandle);
431 if (true == isDebugMode) {
433 serviceTimer = ecore_timer_add(timeout, timerCallback, NULL);
437 ret = service_send_launch_request(serviceHandle,
438 serviceReplyCallback,
440 if (SERVICE_ERROR_NONE != ret) {
441 printf("result: %s\n", "failed");
442 service_destroy(serviceHandle);
446 service_destroy(serviceHandle);
448 printf("result: %s\n", "failed");
452 if (true == isDebugMode) {
453 ecore_main_loop_begin();
456 // This text should be showed for IDE
457 printf("result: %s\n", "launched");
459 } else if (op == 'k') {
460 bool isRunning = false;
462 //checks whether the application is running
463 ret = app_manager_is_running(applicationId, &isRunning);
464 if (APP_MANAGER_ERROR_NONE != ret) {
465 printf("result: %s\n", "failed");
469 if (true == isRunning) {
470 // get app_context for running application
471 // app_context must be released with app_context_destroy
472 app_context_h appCtx = NULL;
473 ret = app_manager_get_app_context(applicationId, &appCtx);
474 if (APP_MANAGER_ERROR_NONE != ret) {
475 printf("result: %s\n", "failed");
479 // terminate app_context_h
480 ret = app_manager_terminate_app(appCtx);
481 if (APP_MANAGER_ERROR_NONE != ret) {
482 printf("result: %s\n", "failed");
483 app_context_destroy(appCtx);
486 printf("result: %s\n", "killed");
487 app_context_destroy(appCtx);
491 printf("result: %s\n", "App isn't running");
494 } else if (op == 'r') {
495 bool isRunning = false;
496 ret = app_manager_is_running(applicationId, &isRunning);
498 if (APP_MANAGER_ERROR_NONE != ret) {
499 printf("result: %s\n", "failed");
503 if (true == isRunning) {
504 printf("result: %s\n", "running");
507 printf("result: %s\n", "not running");
514 UNHANDLED_EXCEPTION_HANDLER_END