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_id; /**< the widget's pkg id */
76 static void free_widget_info(widget_info* widget_info)
79 delete[] widget_info->guid;
80 delete[] widget_info->name;
81 delete[] widget_info->version;
82 delete[] widget_info->pkg_id;
83 delete[] widget_info->app_id;
88 static char* new_strdup(const char *str)
90 size_t size = strlen(str);
91 char* ret = new char[size + 1];
96 static bool attachDbConnection()
98 if (NULL == g_dbConnection.get()) {
100 g_dbConnection.reset(new DBConnection());
101 g_dbConnection->AttachDatabase();
103 Catch(DPL::DB::SqlConnection::Exception::Base) {
104 LogDebug("Fail to connect DB");
111 static bool display_widget_info()
113 if (!attachDbConnection()) {
117 WidgetDAOReadOnlyList widgetList =
118 WrtDB::WidgetDAOReadOnly::getWidgetList();
120 printf("%3s %32s %16s %64s %16s %24s\n",
121 "No", "Name", "Version", "GUID", "Package ID", "App ID");
122 printf("%3s %32s %16s %64s %16s %24s\n",
123 "--", "--", "----", "-------", "-----", "-----");
126 FOREACH(dao, widgetList) {
127 widget_info *info = new widget_info;
128 memset(info, 0x00, sizeof(widget_info));
130 WrtDB::WidgetGUID guid = (*dao)->getGUID();
131 DPL::Optional<DPL::String> version = (*dao)->getVersion();
132 WrtDB::TizenAppId appid = (*dao)->getTzAppId();
133 WrtDB::TizenPkgId pkgid = (*dao)->getTizenPkgId();
137 DPL::Optional<DPL::String> widget_name;
138 DPL::OptionalString dl = (*dao)->getDefaultlocale();
139 WrtDB::WidgetLocalizedInfo localizedInfo;
141 DPL::String languageTag(L"");
142 localizedInfo = (*dao)->getLocalizedInfo(languageTag);
144 localizedInfo = (*dao)->getLocalizedInfo(*dl);
147 widget_name = localizedInfo.name;
149 /*end get WidgetName*/
150 if (!widget_name.IsNull()) {
151 info->name = new_strdup(DPL::ToUTF8String(*widget_name).c_str());
153 if (!version.IsNull()) {
154 info->version = new_strdup(DPL::ToUTF8String(*version).c_str());
156 std::string installedWidgetVersionString;
157 installedWidgetVersionString = "";
158 info->version = new_strdup(installedWidgetVersionString.c_str());
160 if (!guid.IsNull()) {
161 info->guid = new_strdup(DPL::ToUTF8String(*guid).c_str());
164 info->app_id = new_strdup(DPL::ToUTF8String(appid).c_str());
165 info->pkg_id = new_strdup(DPL::ToUTF8String(pkgid).c_str());
167 printf("%3i %32s %16s %64s %16s %24s\n",
169 !info->name ? "[NULL]" : info->name,
170 !info->version ? "[NULL]" : info->version,
171 !info->guid ? "[NULL]" : info->guid,
172 !info->pkg_id ? "[NULL]" : info->pkg_id,
173 !info->app_id ? "[NULL]" : info->app_id);
175 free_widget_info(info);
181 static void print_help(FILE *stream, int /*exit_code*/)
183 fprintf(stream, "Usage : %s [ ... ]\n", program);
186 " -h --help Display this usage information.\n"
187 " -l --list Display installed widgets list\n"
188 " -s [tizen application ID] --start Launch widget with tizen application ID\n"
189 " -k [tizen application ID] --kill Kill widget with tizen application ID\n"
190 " -r [tizen application ID] --is-running Check whether widget is running by tizen application ID,\n"
191 " If widget is running, 0(zero) will be returned.\n"
192 " -d --debug Activate debug mode\n"
193 " -t [second] --timeout Set timeout of response from widget in debug mode\n"
194 " -c [1]or[0] --compliance-mode Set compliancemode\n"
195 " -i [imei] --fake-imei Set fakeimei\n"
196 " -m [meid] --fake-meid Set fakemeid\n"
197 " if you emit this option, 5 seconds is set in debug mode\n"
201 static void sighandler(int signo, siginfo_t *si, void *data);
203 int main(int argc, char* argv[])
205 UNHANDLED_EXCEPTION_HANDLER_BEGIN
207 int next_opt, opt_idx = 0;
208 int timeout = TIMEOUT_DEFAULT;
209 char applicationId[256] = "";
210 char temp_arg[256] = "";
213 bool isDebugMode = false;
214 struct sigaction sigact;
215 bool dispHelp = false;
216 bool dispList = false;
218 service_h serviceHandle = NULL;
219 int ret = SERVICE_ERROR_NONE;
223 static struct option long_options[] = {
224 { "help", no_argument, 0, 'h' },
225 { "list", no_argument, 0, 'l' },
226 { "start", required_argument, 0, 's' },
227 { "kill", required_argument, 0, 'k' },
228 { "is-running", required_argument, 0, 'r' },
229 { "debug", no_argument, 0, 'd' },
230 { "timeout", required_argument, 0, 't' },
231 { "compliance-mode", required_argument, 0, 'c' },
232 { "fake-imei", required_argument, 0, 'i' },
233 { "fake-meid", required_argument, 0, 'm' },
237 if (argv[1] == NULL) {
238 /* exit if any argument doesn't exist */
239 print_help(stdout, 0);
243 if (ROOT_DEFAULT_UID == geteuid()) {
244 if (RETURN_ERROR == setuid(ROOT_DEFAULT_UID)) {
245 perror("Fail to set uid");
248 if (ROOT_DEFAULT_GID == getegid()) {
249 if (RETURN_ERROR == setgid(ROOT_DEFAULT_GID)) {
250 perror("Fail to set gid");
255 next_opt = getopt_long(argc,
257 "hls:k:r:dt:v:c:i:m:",
264 print_help(stdout, 0);
273 if (!display_widget_info()) {
274 printf("Fail to display the list of installed widgets");
283 strncpy(temp_arg, optarg, strlen(optarg));
288 timeout = atoi(optarg);
290 timeout = TIMEOUT_DEFAULT;
296 ret = service_create(&serviceHandle);
297 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
298 LogError("Fail to create service");
303 ret = service_add_extra_data(serviceHandle,
306 if (SERVICE_ERROR_NONE != ret) {
307 LogError("Fail to set debug mode [" << ret << "]");
308 service_destroy(serviceHandle);
313 snprintf(pid, sizeof(pid), "%d", getpid());
314 ret = service_add_extra_data(serviceHandle,
317 if (SERVICE_ERROR_NONE != ret) {
318 LogError("Fail to set pid [" << ret << "]");
319 service_destroy(serviceHandle);
326 strncpy(temp_arg, optarg, strlen(optarg));
327 if (!attachDbConnection()) {
330 if (!strcmp("1", temp_arg)) {
331 WrtDB::GlobalDAO::setComplianceMode(true);
333 WrtDB::GlobalDAO::setComplianceMode(false);
337 strncpy(temp_arg, optarg, strlen(optarg));
338 if (!attachDbConnection()) {
341 WrtDB::GlobalDAO::setComplianceFakeImei(temp_arg);
344 strncpy(temp_arg, optarg, strlen(optarg));
345 if (!attachDbConnection()) {
348 WrtDB::GlobalDAO::setComplianceFakeMeid(temp_arg);
355 print_help(stdout, 0);
358 } while (next_opt != -1);
360 if ((op == 's') || (op == 'k') || (op == 'r')) {
363 if (NULL == g_dbConnection.get()) {
365 g_dbConnection.reset(new DBConnection());
366 g_dbConnection->AttachDatabase();
368 Catch(DPL::DB::SqlConnection::Exception::Base) {
369 LogDebug("Fail to connect DB");
373 DPL::OptionalString normal_str = DPL::FromUTF8String(temp_arg);
374 WrtDB::NormalizeAndTrimSpaceString(normal_str);
375 std::string normal_arg = DPL::ToUTF8String(*normal_str);
377 WidgetDAOReadOnlyList widgetList =
378 WrtDB::WidgetDAOReadOnly::getWidgetList();
379 FOREACH(dao, widgetList) {
380 WrtDB::TizenAppId tizenAppId = (*dao)->getTzAppId();
381 if (!strcmp(DPL::ToUTF8String(tizenAppId).c_str(),
384 temp = DPL::ToUTF8String(tizenAppId);
389 strncpy(applicationId, temp.c_str(), strlen(temp.c_str()));
391 printf("result: %s\n", "failed");
397 /* check if this is request for debug mode, or not */
398 if (true == isDebugMode) {
399 /* wait for return from the widget */
400 sigemptyset(&sigact.sa_mask);
401 sigact.sa_flags = SA_SIGINFO;
402 sigact.sa_restorer = NULL;
403 sigact.sa_sigaction = sighandler;
405 if (sigaction(SIGRTMIN, &sigact, 0) == 1) {
406 printf("result: %s\n", "failed");
410 // case of "-d" option, service_create is already allocated
412 ret = service_create(&serviceHandle);
413 if (SERVICE_ERROR_NONE != ret && NULL == serviceHandle) {
414 printf("result: %s\n", "failed");
419 if (strlen(applicationId) > 0) {
420 // do setuid to '5000' uid to communicate
421 //with webapp using RT signal.
423 group_list[0] = LOGGING_DEFAULT_GID;
425 if (setgroups(sizeof(group_list), group_list) < 0) {
426 printf("result: %s\n", "failed");
430 if (setreuid(WEBAPP_DEFAULT_UID, WEBAPP_DEFAULT_GID) < 0) {
431 printf("result: %s\n", "failed");
436 ret = service_set_package(serviceHandle, applicationId);
437 if (SERVICE_ERROR_NONE != ret) {
438 printf("result: %s\n", "failed");
439 service_destroy(serviceHandle);
444 ret = service_send_launch_request(serviceHandle, NULL, NULL);
445 if (SERVICE_ERROR_NONE != ret) {
446 printf("result: %s\n", "failed");
447 service_destroy(serviceHandle);
451 service_destroy(serviceHandle);
453 printf("result: %s\n", "failed");
457 if (true == isDebugMode) {
458 // wait RTS signal from widget by 5 second
460 printf("result: %s\n", "failed");
463 // This text should be showed for IDE
464 printf("result: %s\n", "launched");
466 } else if (op == 'k') {
467 bool isRunning = false;
469 //checks whether the application is running
470 ret = app_manager_is_running(applicationId, &isRunning);
471 if (APP_MANAGER_ERROR_NONE != ret) {
472 printf("result: %s\n", "failed");
476 if (true == isRunning) {
477 // get app_context for running application
478 // app_context must be released with app_context_destroy
479 app_context_h appCtx = NULL;
480 ret = app_manager_get_app_context(applicationId, &appCtx);
481 if (APP_MANAGER_ERROR_NONE != ret) {
482 printf("result: %s\n", "failed");
486 // terminate app_context_h
487 ret = app_manager_terminate_app(appCtx);
488 if (APP_MANAGER_ERROR_NONE != ret) {
489 printf("result: %s\n", "failed");
490 app_context_destroy(appCtx);
493 printf("result: %s\n", "killed");
494 app_context_destroy(appCtx);
498 printf("result: %s\n", "App isn't running");
501 } else if (op == 'r') {
502 bool isRunning = false;
503 ret = app_manager_is_running(applicationId, &isRunning);
505 if (APP_MANAGER_ERROR_NONE != ret) {
506 printf("result: %s\n", "failed");
510 if (true == isRunning) {
511 printf("result: %s\n", "running");
514 printf("result: %s\n", "not running");
521 UNHANDLED_EXCEPTION_HANDLER_END
524 static void sighandler(int signo, siginfo_t *si, void* /*data*/)
526 /* check if this signal is type of RTS */
527 if (si->si_code == SI_QUEUE) {
529 //printf("RTS pid : %d\n", si->si_pid);
530 //port = (int) si->si_value.sival_ptr;
531 //printf("RTS debug port : %d\n", port);
532 // This sival_int is wrt's status (like WRT_SUCCESS..)
533 // enum WRT_SUCCESS is 0
534 if (si->si_value.sival_int > 0) {
535 printf("port: %d\n", (int)si->si_value.sival_int);
536 printf("result: %s\n", "launched");
538 printf("result: %s\n", "failed");
541 printf("Not RT signal : %d\n", signo);