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.
13 #include "base/at_exit.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h"
18 #include "dbus/message.h"
19 #include "dbus/object_proxy.h"
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"
26 #include "xwalk/application/common/id_util.h"
27 #include "xwalk/application/tools/linux/xwalk_tizen_user.h"
30 using xwalk::application::ApplicationData;
31 using xwalk::application::ApplicationStorage;
32 using xwalk::application::PackageInstaller;
34 static char* install_path;
35 static char* uninstall_appid;
37 static gint debugging_port = -1;
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 },
49 #if defined(SHARED_PROCESS_MODE)
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");
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");
65 scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
66 dbus::ObjectProxy* app_proxy =
67 bus->GetObjectProxy(xwalk_service_name, kRunningManagerDBusPath);
71 dbus::MethodCall method_call(
72 xwalk_running_manager_iface, "TerminateIfRunning");
73 dbus::MessageWriter writer(&method_call);
74 writer.AppendString(app_id);
76 app_proxy->CallMethodAndBlock(&method_call, 1000);
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");
85 scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
86 dbus::ObjectProxy* app_proxy =
89 kRunningManagerDBusPath);
93 dbus::MethodCall method_call(
94 xwalk_running_manager_iface, "EnableRemoteDebugging");
95 dbus::MessageWriter writer(&method_call);
96 writer.AppendUint32(debugging_port);
98 app_proxy->CallMethodAndBlock(&method_call, 1000);
100 if (debugging_port > 0) {
101 g_print("Remote debugging enabled at port '%d'\n", debugging_port);
103 g_print("Remote debugging has been disabled\n");
109 bool list_applications(ApplicationStorage* storage) {
110 std::vector<std::string> app_ids;
111 if (!storage->GetInstalledApplicationIDs(app_ids))
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));
120 g_print("Failed to obtain app data for xwalk id: %s\n",
121 app_ids.at(i).c_str());
124 g_print("%s %s\n", app_ids.at(i).c_str(), app_data->Name().c_str());
126 g_print("-----------------------------------------------------\n");
131 int main(int argc, char* argv[]) {
132 setlocale(LC_ALL, "");
133 GError* error = NULL;
134 GOptionContext* context;
135 bool success = false;
137 #if !GLIB_CHECK_VERSION(2, 36, 0)
138 // g_type_init() is deprecated on GLib since 2.36, Tizen has 2.32.
142 #if defined(OS_TIZEN)
143 if (xwalk_tizen_check_user_app())
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);
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());
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);
170 } else if (uninstall_appid) {
171 #if defined(SHARED_PROCESS_MODE)
172 TerminateIfRunning(uninstall_appid);
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);
180 g_print("Couldn't enable remote debugging for no shared process mode!");
183 success = list_applications(storage.get());
186 return success ? 0 : 1;