261cdefdde5713bce3645f9cc140c4117d01d221
[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
12 #include "xwalk/application/tools/linux/dbus_connection.h"
13 #include "xwalk/application/tools/linux/xwalk_tizen_user.h"
14
15 static const char* xwalk_service_name = "org.crosswalkproject.Runtime1";
16 static const char* xwalk_installed_path = "/installed1";
17 static const char* xwalk_installed_iface =
18     "org.crosswalkproject.Installed.Manager1";
19 static const char* xwalk_installed_app_iface =
20     "org.crosswalkproject.Installed.Application1";
21
22 static char* install_path;
23 static char* uninstall_appid;
24 static GDBusConnection* g_connection;
25
26 static GOptionEntry entries[] = {
27   { "install", 'i', 0, G_OPTION_ARG_STRING, &install_path,
28     "Path of the application to be installed/updated", "PATH" },
29   { "uninstall", 'u', 0, G_OPTION_ARG_STRING, &uninstall_appid,
30     "Uninstall the application with this appid", "APPID" },
31   { NULL }
32 };
33
34 static bool install_application(const char* path) {
35   GError* error = NULL;
36   GDBusProxy* proxy;
37   bool ret;
38   GVariant* result = NULL;
39
40   proxy = g_dbus_proxy_new_sync(
41       g_connection,
42       G_DBUS_PROXY_FLAGS_NONE, NULL, xwalk_service_name,
43       xwalk_installed_path, xwalk_installed_iface, NULL, &error);
44   if (!proxy) {
45     g_print("Couldn't create proxy for '%s': %s\n", xwalk_installed_iface,
46             error->message);
47     g_error_free(error);
48     ret = false;
49     goto done;
50   }
51
52   result = g_dbus_proxy_call_sync(proxy, "Install",
53                                   g_variant_new("(s)", path),
54                                   G_DBUS_CALL_FLAGS_NONE,
55                                   -1, NULL, &error);
56   if (!result) {
57     g_print("Installing application failed: %s\n", error->message);
58     g_error_free(error);
59     ret = false;
60     goto done;
61   }
62
63   const char* object_path;
64
65   g_variant_get(result, "(o)", &object_path);
66   g_print("Application installed/updated with path '%s'\n", object_path);
67   g_variant_unref(result);
68
69   ret = true;
70
71  done:
72   if (proxy)
73     g_object_unref(proxy);
74
75   return ret;
76 }
77
78 static bool uninstall_application(GDBusObjectManager* installed,
79                                   const char* appid) {
80   GList* objects = g_dbus_object_manager_get_objects(installed);
81   GList* l;
82   bool ret = false;
83
84   for (l = objects; l; l = l->next) {
85     GDBusObject* object = reinterpret_cast<GDBusObject*>(l->data);
86     GDBusInterface* iface = g_dbus_object_get_interface(
87         object,
88         xwalk_installed_app_iface);
89     if (!iface)
90       continue;
91
92     GDBusProxy* proxy = G_DBUS_PROXY(iface);
93
94     GVariant* value = g_dbus_proxy_get_cached_property(proxy, "AppID");
95     if (!value) {
96       g_object_unref(iface);
97       continue;
98     }
99
100     const char* id;
101     g_variant_get(value, "s", &id);
102
103     if (g_strcmp0(appid, id)) {
104       g_object_unref(iface);
105       continue;
106     }
107
108     GError* error = NULL;
109     GVariant* result = g_dbus_proxy_call_sync(proxy, "Uninstall", NULL,
110                                               G_DBUS_CALL_FLAGS_NONE,
111                                               -1, NULL, &error);
112     if (!result) {
113       g_print("Uninstalling application failed: %s\n", error->message);
114       g_error_free(error);
115       g_object_unref(iface);
116       ret = false;
117       goto done;
118     }
119
120     g_object_unref(iface);
121     ret = true;
122     goto done;
123   }
124
125   g_print("Application ID '%s' could not be found\n", appid);
126
127  done:
128   g_list_free_full(objects, g_object_unref);
129
130   return ret;
131 }
132
133 static void list_applications(GDBusObjectManager* installed) {
134   GList* objects = g_dbus_object_manager_get_objects(installed);
135   GList* l;
136
137   for (l = objects; l; l = l->next) {
138     GDBusObject* object = reinterpret_cast<GDBusObject*>(l->data);
139     GDBusInterface* iface = g_dbus_object_get_interface(
140         object,
141         xwalk_installed_app_iface);
142     if (!iface)
143       continue;
144
145     GDBusProxy* proxy = G_DBUS_PROXY(iface);
146     GVariant* id_variant;
147     id_variant = g_dbus_proxy_get_cached_property(proxy, "AppID");
148     if (!id_variant) {
149       g_object_unref(iface);
150       continue;
151     }
152
153     const char* id;
154     g_variant_get(id_variant, "s", &id);
155
156     GVariant* name_variant;
157     name_variant = g_dbus_proxy_get_cached_property(proxy, "Name");
158     if (!name_variant) {
159       g_object_unref(iface);
160       continue;
161     }
162
163     const char* name;
164     g_variant_get(name_variant, "s", &name);
165
166     g_print("%s\t%s\n", id, name);
167
168     g_object_unref(iface);
169   }
170
171   g_list_free_full(objects, g_object_unref);
172 }
173
174 int main(int argc, char* argv[]) {
175   GError* error = NULL;
176   GOptionContext* context;
177   bool success;
178
179 #if !GLIB_CHECK_VERSION(2, 36, 0)
180   // g_type_init() is deprecated on GLib since 2.36, Tizen has 2.32.
181   g_type_init();
182 #endif
183
184   if (xwalk_tizen_set_home_for_user_app())
185     exit(1);
186
187   context = g_option_context_new("- Crosswalk Application Management");
188   g_option_context_add_main_entries(context, entries, NULL);
189   if (!g_option_context_parse(context, &argc, &argv, &error)) {
190     g_print("option parsing failed: %s\n", error->message);
191     exit(1);
192   }
193
194   g_connection = get_session_bus_connection(&error);
195   if (!g_connection) {
196     fprintf(stderr, "Couldn't get the session bus connection: %s\n",
197             error->message);
198     exit(1);
199   }
200
201   GDBusObjectManager* installed_om = g_dbus_object_manager_client_new_sync(
202       g_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
203       xwalk_service_name, xwalk_installed_path,
204       NULL, NULL, NULL, NULL, &error);
205   if (!installed_om) {
206     g_print("Service '%s' could not be reached: %s\n", xwalk_service_name,
207             error->message);
208     exit(1);
209   }
210
211   // GDBus may return a valid ObjectManager even if it fails to auto activate
212   // the proper service name. We should check 'name-owner' property to make sure
213   // the service is working. See GDBusObjectManager documentation.
214   gchar* name_owner = NULL;
215   g_object_get(installed_om, "name-owner", &name_owner, NULL);
216   if (!name_owner) {
217     g_print("Service '%s' could not be activated.\n", xwalk_service_name);
218     exit(1);
219   }
220   g_free(name_owner);
221
222   if (install_path) {
223     success = install_application(install_path);
224   } else if (uninstall_appid) {
225     success = uninstall_application(installed_om, uninstall_appid);
226   } else {
227     g_print("Application ID                       Application Name\n");
228     g_print("-----------------------------------------------------\n");
229     list_applications(installed_om);
230     g_print("-----------------------------------------------------\n");
231     success = true;
232   }
233
234   return success ? 0 : 1;
235 }