Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / tools / linux / xwalkctl_main.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <stdio.h>
8
9 #include <glib.h>
10 #include <gio/gio.h>
11 #include <locale.h>
12
13 #include "base/at_exit.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h"
16
17 #include "dbus/bus.h"
18 #include "dbus/message.h"
19 #include "dbus/object_proxy.h"
20
21 #include "xwalk/application/common/application_storage.h"
22 #include "xwalk/application/common/installer/package_installer.h"
23 #include "xwalk/application/tools/linux/dbus_connection.h"
24 #include "xwalk/runtime/common/xwalk_paths.h"
25 #if defined(OS_TIZEN)
26 #include "xwalk/application/common/id_util.h"
27 #include "xwalk/application/tools/linux/xwalk_tizen_user.h"
28 #endif
29
30 using xwalk::application::ApplicationData;
31 using xwalk::application::ApplicationStorage;
32 using xwalk::application::PackageInstaller;
33
34 static char* install_path;
35 static char* uninstall_appid;
36
37 static gint debugging_port = -1;
38
39 static GOptionEntry entries[] = {
40   { "install", 'i', 0, G_OPTION_ARG_STRING, &install_path,
41     "Path of the application to be installed/updated", "PATH" },
42   { "uninstall", 'u', 0, G_OPTION_ARG_STRING, &uninstall_appid,
43     "Uninstall the application with this appid", "APPID" },
44   { "debugging_port", 'd', 0, G_OPTION_ARG_INT, &debugging_port,
45     "Enable remote debugging, port number 0 means to disable", NULL },
46   { NULL }
47 };
48
49 #if defined(SHARED_PROCESS_MODE)
50 namespace {
51
52 const char xwalk_service_name[] = "org.crosswalkproject.Runtime1";
53 const char xwalk_running_manager_iface[] =
54     "org.crosswalkproject.Running.Manager1";
55 const dbus::ObjectPath kRunningManagerDBusPath("/running1");
56
57 }  // namespace
58
59 static void TerminateIfRunning(const std::string& app_id) {
60   dbus::Bus::Options options;
61 #if defined(OS_TIZEN_MOBILE)
62   options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
63   options.address.assign("unix:path=/run/user/app/dbus/user_bus_socket");
64 #endif
65   scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
66   dbus::ObjectProxy* app_proxy =
67       bus->GetObjectProxy(xwalk_service_name, kRunningManagerDBusPath);
68   if (!app_proxy)
69     return;
70
71   dbus::MethodCall method_call(
72       xwalk_running_manager_iface, "TerminateIfRunning");
73   dbus::MessageWriter writer(&method_call);
74   writer.AppendString(app_id);
75
76   app_proxy->CallMethodAndBlock(&method_call, 1000);
77 }
78
79 static bool enable_remote_debugging(gint debugging_port) {
80   dbus::Bus::Options options;
81 #if defined(OS_TIZEN_MOBILE)
82   options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
83   options.address.assign("unix:path=/run/user/app/dbus/user_bus_socket");
84 #endif
85   scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
86   dbus::ObjectProxy* app_proxy =
87       bus->GetObjectProxy(
88           xwalk_service_name,
89           kRunningManagerDBusPath);
90   if (!app_proxy)
91     return false;
92
93   dbus::MethodCall method_call(
94       xwalk_running_manager_iface, "EnableRemoteDebugging");
95   dbus::MessageWriter writer(&method_call);
96   writer.AppendUint32(debugging_port);
97
98   app_proxy->CallMethodAndBlock(&method_call, 1000);
99
100   if (debugging_port > 0) {
101     g_print("Remote debugging enabled at port '%d'\n", debugging_port);
102   } else {
103     g_print("Remote debugging has been disabled\n");
104   }
105   return true;
106 }
107 #endif
108
109 bool list_applications(ApplicationStorage* storage) {
110   std::vector<std::string> app_ids;
111   if (!storage->GetInstalledApplicationIDs(app_ids))
112     return false;
113
114   g_print("Application ID                       Application Name\n");
115   g_print("-----------------------------------------------------\n");
116   for (unsigned i = 0; i < app_ids.size(); ++i) {
117     scoped_refptr<ApplicationData> app_data =
118         storage->GetApplicationData(app_ids.at(i));
119     if (!app_data) {
120       g_print("Failed to obtain app data for xwalk id: %s\n",
121               app_ids.at(i).c_str());
122       continue;
123     }
124     g_print("%s  %s\n", app_ids.at(i).c_str(), app_data->Name().c_str());
125   }
126   g_print("-----------------------------------------------------\n");
127
128   return true;
129 }
130
131 int main(int argc, char* argv[]) {
132   setlocale(LC_ALL, "");
133   GError* error = NULL;
134   GOptionContext* context;
135   bool success = false;
136
137 #if !GLIB_CHECK_VERSION(2, 36, 0)
138   // g_type_init() is deprecated on GLib since 2.36, Tizen has 2.32.
139   g_type_init();
140 #endif
141
142 #if defined(OS_TIZEN)
143   if (xwalk_tizen_check_user_app())
144     exit(1);
145 #endif
146
147   context = g_option_context_new("- Crosswalk Application Management");
148   g_option_context_add_main_entries(context, entries, NULL);
149   if (!g_option_context_parse(context, &argc, &argv, &error)) {
150     g_print("option parsing failed: %s\n", error->message);
151     exit(1);
152   }
153
154   base::AtExitManager at_exit;
155   base::FilePath data_path;
156   xwalk::RegisterPathProvider();
157   PathService::Get(xwalk::DIR_DATA_PATH, &data_path);
158   scoped_ptr<ApplicationStorage> storage(new ApplicationStorage(data_path));
159   scoped_ptr<PackageInstaller> installer =
160       PackageInstaller::Create(storage.get());
161
162   if (install_path) {
163     std::string app_id;
164     const base::FilePath& path = base::FilePath(install_path);
165     success = installer->Install(path, &app_id);
166     if (!success && storage->Contains(app_id)) {
167       g_print("trying to update %s\n", app_id.c_str());
168       success = installer->Update(app_id, path);
169     }
170   } else if (uninstall_appid) {
171 #if defined(SHARED_PROCESS_MODE)
172     TerminateIfRunning(uninstall_appid);
173 #endif
174     success = installer->Uninstall(uninstall_appid);
175   } else if (debugging_port >= 0) {
176 #if defined(SHARED_PROCESS_MODE)
177     // Deal with the case "xwalkctl -d PORT_NUMBER"
178     success = enable_remote_debugging(debugging_port);
179 #else
180     g_print("Couldn't enable remote debugging for no shared process mode!");
181 #endif
182   } else {
183     success = list_applications(storage.get());
184   }
185
186   return success ? 0 : 1;
187 }