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>
37 #define TIMEOUT_DEFAULT 10
38 #define ROOT_DEFAULT_UID 0
39 #define ROOT_DEFAULT_GID 0
40 #define WEBAPP_DEFAULT_UID 5000
41 #define WEBAPP_DEFAULT_GID 5000
42 #define LOGGING_DEFAULT_GID 6509
43 #define RETURN_ERROR -1
45 static const char *program;
52 WrtDB::WrtDatabase::attachToThreadRW();
57 WrtDB::WrtDatabase::detachFromThread();
61 static std::unique_ptr<DBConnection> g_dbConnection;
65 char* guid; /**< the widget's id
66 (read from its config.xml during installation)*/
67 char* name; /**< the widget's name
68 (read from its config.xml during installation)*/
69 char* version; /**< the widget's varsion
70 (read from its config.xml during installation)*/
71 char* pkg_name; /**< the widget's pkg name */
74 static void free_widget_info(widget_info* widget_info)
77 delete[] widget_info->guid;
78 delete[] widget_info->name;
79 delete[] widget_info->version;
80 delete[] widget_info->pkg_name;
85 static char* new_strdup(const char *str)
87 size_t size = strlen(str);
88 char* ret = new char[size + 1];
93 static bool attachDbConnection()
95 if (NULL == g_dbConnection.get()) {
97 g_dbConnection.reset(new DBConnection());
98 g_dbConnection->AttachDatabase();
100 Catch (DPL::DB::SqlConnection::Exception::Base) {
101 LogDebug("Fail to connect DB");
108 static bool display_widget_info()
110 if(!attachDbConnection()) return FALSE;
112 WidgetDAOReadOnlyList widgetList =
113 WrtDB::WidgetDAOReadOnly::getWidgetList();
115 printf("%3s %32s %16s %64s %16s\n",
116 "No", "Name", "Version", "GUID", "Package Name");
117 printf("%3s %32s %16s %64s %16s\n",
118 "--", "--", "----", "-------", "----");
121 FOREACH(dao, widgetList) {
122 widget_info *info = new widget_info;
123 memset(info, 0x00, sizeof(widget_info));
125 WrtDB::WidgetGUID guid = (*dao)->getGUID();
126 DPL::Optional<DPL::String> version = (*dao)->getVersion();
127 WrtDB::WidgetPkgName package_name = (*dao)->getPkgName();
130 DPL::Optional<DPL::String> widget_name;
131 DPL::OptionalString dl = (*dao)->getDefaultlocale();
132 WrtDB::WidgetLocalizedInfo localizedInfo;
134 DPL::String languageTag(L"");
135 localizedInfo = (*dao)->getLocalizedInfo(languageTag);
137 localizedInfo = (*dao)->getLocalizedInfo(*dl);
140 widget_name = localizedInfo.name;
142 /*end get WidgetName*/
143 if (!widget_name.IsNull()) {
144 info->name = new_strdup(DPL::ToUTF8String(*widget_name).c_str());
146 if (!version.IsNull()) {
147 info->version = new_strdup(DPL::ToUTF8String(*version).c_str());
149 std::string installedWidgetVersionString;
150 installedWidgetVersionString = "";
151 info->version = new_strdup(installedWidgetVersionString.c_str());
153 if (!guid.IsNull()) {
154 info->guid = new_strdup(DPL::ToUTF8String(*guid).c_str());
157 info->pkg_name = new_strdup(DPL::ToUTF8String(package_name).c_str());
160 printf("%3i %32s %16s %64s %16s\n",
162 !info->name ? "[NULL]" : info->name,
163 !info->version ? "[NULL]" : info->version,
164 !info->guid ? "[NULL]" : info->guid,
165 !info->pkg_name ? "[NULL]" : info->pkg_name);
167 free_widget_info(info);
173 static void print_help(FILE *stream, int /*exit_code*/)
175 fprintf(stream, "Usage : %s [ ... ]\n", program);
177 " -h --help Display this usage information.\n"
178 " -l --list Display installed widgets list\n"
179 " -s [GUID]or[PkgName] --start Launch widget with package name or GUID\n"
180 " -k [GUID]or[PkgName] --kill Kill widget with package name or GUID\n"
181 " -r [GUID]or[PkgName] --is-running Check whether widget is running by package name or GUID,\n"
182 " If widget is running, 0(zero) will be returned.\n"
183 " -d --debug Activate debug mode\n"
184 " -t [second] --timeout Set timeout of response from widget in debug mode\n"
185 " -v [1]or[0] --developer-mode Set developermode\n"
186 " -c [1]or[0] --compliance-mode Set compliancemode\n"
187 " -i [imei] --fake-imei Set fakeimei\n"
188 " -m [meid] --fake-meid Set fakemeid\n"
189 " if you emit this option, 5 seconds is set in debug mode\n"
193 static void sighandler(int signo, siginfo_t *si, void *data);
195 int main(int argc, char* argv[])
197 UNHANDLED_EXCEPTION_HANDLER_BEGIN
199 int next_opt, opt_idx = 0;
200 int timeout = TIMEOUT_DEFAULT;
201 char pkgname[256] = "";
202 char temp_arg[256] = "";
205 bool isDebugMode = false;
206 struct sigaction sigact;
207 bool dispHelp = false;
208 bool dispList = false;
210 service_h serviceHandle = NULL;
211 int ret = SERVICE_ERROR_NONE;
215 static struct option long_options[] = {
216 {"help", no_argument, 0, 'h'},
217 {"list", no_argument, 0, 'l'},
218 {"start", required_argument, 0, 's'},
219 {"kill", required_argument, 0, 'k'},
220 {"is-running", required_argument, 0, 'r'},
221 {"debug", no_argument, 0, 'd'},
222 {"timeout", required_argument, 0, 't'},
223 {"developer-mode", required_argument, 0, 'v'},
224 {"compliance-mode", required_argument, 0, 'c'},
225 {"fake-imei", required_argument, 0, 'i'},
226 {"fake-meid", required_argument, 0, 'm'},
230 if (argv[1] == NULL) {
231 /* exit if any argument doesn't exist */
232 print_help(stdout, 0);
236 if (ROOT_DEFAULT_UID == geteuid()) {
237 if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) {
238 perror("Fail to set uid");
241 if (ROOT_DEFAULT_GID == getegid()) {
242 if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) {
243 perror("Fail to set gid");
248 next_opt = getopt_long(argc,
250 "hls:k:r:dt:v:c:i:m:",
257 print_help(stdout, 0);
265 if (!display_widget_info()) {
266 printf("Fail to display the list of installed widgets");
275 strncpy(temp_arg, optarg, strlen(optarg));
280 timeout = atoi(optarg);
282 timeout = TIMEOUT_DEFAULT;
288 ret = service_create(&serviceHandle);
289 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
290 LogError("Fail to create service");
295 ret = service_add_extra_data(serviceHandle,
298 if (SERVICE_ERROR_NONE != ret) {
299 LogError("Fail to set debug mode [" << ret << "]");
300 service_destroy(serviceHandle);
305 snprintf(pid, sizeof(pid), "%d", getpid());
306 ret = service_add_extra_data(serviceHandle,
309 if (SERVICE_ERROR_NONE != ret) {
310 LogError("Fail to set pid [" << ret << "]");
311 service_destroy(serviceHandle);
318 strncpy(temp_arg, optarg, strlen(optarg));
319 if(!attachDbConnection()) return FALSE;
320 if (!strcmp("1", temp_arg)) {
321 WrtDB::GlobalDAO::SetDeveloperMode(true);
323 WrtDB::GlobalDAO::SetDeveloperMode(false);
327 strncpy(temp_arg, optarg, strlen(optarg));
328 if(!attachDbConnection()) return FALSE;
329 if(!strcmp("1", temp_arg)) {
330 WrtDB::GlobalDAO::setComplianceMode(true);
332 WrtDB::GlobalDAO::setComplianceMode(false);
336 strncpy(temp_arg, optarg, strlen(optarg));
337 if(!attachDbConnection()) return FALSE;
338 WrtDB::GlobalDAO::setComplianceFakeImei(temp_arg);
341 strncpy(temp_arg, optarg, strlen(optarg));
342 if(!attachDbConnection()) return FALSE;
343 WrtDB::GlobalDAO::setComplianceFakeMeid(temp_arg);
350 print_help(stdout, 0);
353 } while (next_opt != -1);
355 if ((op == 's') || (op == 'k') || (op =='r')) {
358 if (NULL == g_dbConnection.get()) {
360 g_dbConnection.reset(new DBConnection());
361 g_dbConnection->AttachDatabase();
363 Catch (DPL::DB::SqlConnection::Exception::Base) {
364 LogDebug("Fail to connect DB");
368 DPL::OptionalString normal_str = DPL::FromUTF8String(temp_arg);
369 WrtDB::NormalizeAndTrimSpaceString(normal_str);
370 std::string normal_arg = DPL::ToUTF8String(*normal_str);
372 WidgetDAOReadOnlyList widgetList =
373 WrtDB::WidgetDAOReadOnly::getWidgetList();
374 FOREACH(dao, widgetList) {
375 WrtDB::WidgetGUID d_guid = (*dao)->getGUID();
376 WrtDB::WidgetPkgName d_pkgname = (*dao)->getPkgName();
377 if (!d_guid.IsNull() &&
378 !strcmp(DPL::ToUTF8String(*d_guid).c_str(), temp_arg))
380 WrtDB::WidgetPkgName package_name = (*dao)->getPkgName();
381 temp = DPL::ToUTF8String(package_name);
384 if (!strcmp(DPL::ToUTF8String(d_pkgname).c_str(),
385 normal_arg.c_str())) {
386 WrtDB::WidgetPkgName package_name = (*dao)->getPkgName();
387 temp = DPL::ToUTF8String(package_name);
393 strncpy(pkgname, temp.c_str(), strlen(temp.c_str()));
395 printf("result: %s\n", "failed");
401 /* check if this is request for debug mode, or not */
402 if (true == isDebugMode) {
403 /* wait for return from the widget */
404 sigemptyset(&sigact.sa_mask);
405 sigact.sa_flags = SA_SIGINFO;
406 sigact.sa_restorer = NULL;
407 sigact.sa_sigaction = sighandler;
409 if (sigaction(SIGRTMIN, &sigact, 0) == 1) {
410 printf("result: %s\n", "failed");
414 // case of "-d" option, service_create is already allocated
416 ret = service_create(&serviceHandle);
417 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
418 printf("result: %s\n", "failed");
423 if (strlen(pkgname) > 0) {
424 // do setuid to '5000' uid to communicate
425 //with webapp using RT signal.
427 group_list[0] = LOGGING_DEFAULT_GID;
429 if(setgroups(sizeof(group_list), group_list) < 0) {
430 printf("result: %s\n", "failed");
434 if(setreuid(WEBAPP_DEFAULT_UID, WEBAPP_DEFAULT_GID) < 0) {
435 printf("result: %s\n", "failed");
440 ret = service_set_package(serviceHandle, pkgname);
441 if (SERVICE_ERROR_NONE != ret) {
442 printf("result: %s\n", "failed");
443 service_destroy(serviceHandle);
448 ret = service_send_launch_request(serviceHandle, NULL, NULL);
449 if (SERVICE_ERROR_NONE != ret) {
450 printf("result: %s\n", "failed");
451 service_destroy(serviceHandle);
455 service_destroy(serviceHandle);
457 printf("result: %s\n", "failed");
461 if (true == isDebugMode) {
462 // wait RTS signal from widget by 5 second
464 printf("result: %s\n", "failed");
467 // This text should be showed for IDE
468 printf("result: %s\n", "launched");
470 } else if (op == 'k') {
471 bool isRunning = false;
473 //checks whether the application is running
474 ret = app_manager_is_running(pkgname, &isRunning);
475 if (APP_MANAGER_ERROR_NONE != ret) {
476 printf("result: %s\n", "failed");
480 if (true == isRunning) {
481 // get app_context for running application
482 // app_context must be released with app_context_destroy
483 app_context_h appCtx = NULL;
484 ret = app_manager_get_app_context(pkgname, &appCtx);
485 if (APP_MANAGER_ERROR_NONE != ret) {
486 printf("result: %s\n", "failed");
490 // terminate app_context_h
491 ret = app_manager_terminate_app(appCtx);
492 if (APP_MANAGER_ERROR_NONE != ret) {
493 printf("result: %s\n", "failed");
494 app_context_destroy(appCtx);
497 printf("result: %s\n", "killed");
498 app_context_destroy(appCtx);
502 printf("result: %s\n", "App isn't running");
505 } else if (op == 'r') {
506 bool isRunning = false;
508 ret = app_manager_is_running(pkgname, &isRunning);
510 if (APP_MANAGER_ERROR_NONE != ret) {
511 printf("result: %s\n", "failed");
515 if (true == isRunning) {
516 printf("result: %s\n", "running");
519 printf("result: %s\n", "not running");
526 UNHANDLED_EXCEPTION_HANDLER_END
529 static void sighandler(int signo, siginfo_t *si, void* /*data*/)
531 /* check if this signal is type of RTS */
532 if (si->si_code == SI_QUEUE) {
534 //printf("RTS pid : %d\n", si->si_pid);
535 //port = (int) si->si_value.sival_ptr;
536 //printf("RTS debug port : %d\n", port);
537 // This sival_int is wrt's status (like WRT_SUCCESS..)
538 // enum WRT_SUCCESS is 0
539 if (si->si_value.sival_int > 0) {
540 printf("port: %d\n", (int)si->si_value.sival_int);
541 printf("result: %s\n", "launched");
543 printf("result: %s\n", "failed");
546 printf("Not RT signal : %d\n", signo);