4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7 * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
26 * comm_client library using gdbus
38 #include "comm_config.h"
39 #include "comm_client.h"
40 #include "comm_debug.h"
46 /* Storing status_cb */
47 struct signal_callback_data {
55 guint subscription_id;
56 GDBusConnection *conn;
57 struct signal_callback_data *sig_cb_data;
60 static int __get_signal_type(const char *name)
65 if (strcmp(name, COMM_STATUS_BROADCAST_SIGNAL_STATUS) == 0)
66 return COMM_STATUS_BROADCAST_ALL;
67 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_INSTALL) == 0)
68 return COMM_STATUS_BROADCAST_INSTALL;
69 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_UNINSTALL) == 0)
70 return COMM_STATUS_BROADCAST_UNINSTALL;
71 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_MOVE) == 0)
72 return COMM_STATUS_BROADCAST_MOVE;
73 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS) == 0)
74 return COMM_STATUS_BROADCAST_INSTALL_PROGRESS;
75 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_UPGRADE) == 0)
76 return COMM_STATUS_BROADCAST_UPGRADE;
77 else if (strcmp(name, COMM_STATUS_BROADCAST_EVENT_GET_SIZE) == 0)
78 return COMM_STATUS_BROADCAST_GET_SIZE;
84 * signal handler filter
85 * Filter signal, and run user callback
87 void _on_signal_handle_filter(GDBusConnection *conn,
88 const gchar *sender_name,
89 const gchar *object_path,
90 const gchar *interface_name,
91 const gchar *signal_name,
95 if (interface_name && strcmp(interface_name, "org.tizen.pkgmgr.signal")) {
96 DBG("Interface name did not match. Drop the message");
101 /* Values to be received by signal */
104 char *pkg_type = NULL;
109 /* User's signal handler */
110 struct signal_callback_data *sig_cb_data;
112 sig_cb_data = (struct signal_callback_data *)user_data;
116 status_type = __get_signal_type(signal_name);
117 if (status_type < 0 || !(status_type & sig_cb_data->type))
120 g_variant_get(parameters, "(u&s&s&s&s&s)",
121 &target_uid, &req_id, &pkg_type, &pkgid, &key, &val);
123 /* Run signal callback if exist */
124 if (sig_cb_data && sig_cb_data->cb)
125 sig_cb_data->cb(sig_cb_data->cb_data, target_uid, req_id,
126 pkg_type, pkgid, key, val);
132 * signal_callback_data free function
135 void _free_sig_cb_data(void *data)
137 struct signal_callback_data *sig_cb_data = NULL;
138 sig_cb_data = (struct signal_callback_data *)data;
147 * Create a new comm_client object
149 comm_client *comm_client_new(void)
151 GError *error = NULL;
152 comm_client *cc = NULL;
154 /* Allocate memory for ADT:comm_client */
155 #if !GLIB_CHECK_VERSION(2,35,0)
158 cc = calloc(1, sizeof(comm_client));
164 /* Connect to gdbus. Gets shared BUS */
165 cc->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
167 ERR("gdbus connection error (%s)", error->message);
171 if (NULL == cc->conn) {
172 ERR("gdbus connection is not set, even gdbus error isn't raised");
184 * Free comm_client object
186 int comm_client_free(comm_client *cc)
190 if (!(cc->conn) || g_dbus_connection_is_closed(cc->conn)) {
191 ERR("Invalid gdbus connection");
195 if (cc->sig_cb_data) {
196 g_dbus_connection_signal_unsubscribe(cc->conn, cc->subscription_id);
197 /* TODO: Is it needed to free cc->sig_cb_data here? */
198 /* _free_sig_cb_data(cc->sig_cb_data); */
202 /* flush remaining buffer: blocking mode */
203 g_dbus_connection_flush_sync(cc->conn, NULL, NULL);
205 /* Free signal filter if signal callback is exist */
207 /* just unref because it is shared BUS.
208 If ref count is 0 it will get free'd automatically
210 g_object_unref(cc->conn);
220 comm_client_request(comm_client *cc, const char *req_id, const int req_type,
221 const char *pkg_type, const char *pkgid, const char *args,
222 uid_t uid, int is_block)
224 GError *error = NULL;
229 proxy = g_dbus_proxy_new_sync(cc->conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
230 COMM_PKGMGR_DBUS_SERVICE, COMM_PKGMGR_DBUS_OBJECT_PATH,
231 COMM_PKGMGR_DBUS_INTERFACE, NULL, &error);
233 ERR("failed to get proxy object: %s", error->message);
238 /* Assign default values if NULL (NULL is not allowed) */
240 req_id = "tmp_reqid";
241 if (pkg_type == NULL)
248 result = g_dbus_proxy_call_sync(proxy, "Request", g_variant_new("(sisssi)", req_id, req_type, pkg_type, pkgid, args, uid),
249 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
250 if (result == NULL) {
251 ERR("failed to call %s", error->message);
253 g_object_unref(proxy);
257 g_variant_get(result, "(i)", &rc);
259 return rc == 0 ? COMM_RET_OK : COMM_RET_ERROR;
263 * Set a callback for status signal
266 comm_client_set_status_callback(int comm_status_type, comm_client *cc, status_cb cb, void *cb_data)
268 int r = COMM_RET_ERROR;
271 return COMM_RET_ERROR;
273 /* Create new sig_cb_data */
274 cc->sig_cb_data = calloc(1, sizeof(struct signal_callback_data));
275 if ( cc->sig_cb_data ) {
276 (cc->sig_cb_data)->type = comm_status_type;
277 (cc->sig_cb_data)->cb = cb;
278 (cc->sig_cb_data)->cb_data = cb_data;
283 /* Add a filter for signal */
284 cc->subscription_id = g_dbus_connection_signal_subscribe(cc->conn, NULL, "org.tizen.pkgmgr.signal",
285 NULL, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
286 _on_signal_handle_filter, (gpointer)cc->sig_cb_data, _free_sig_cb_data);
287 if (!cc->subscription_id) {
288 ERR("Failed to add filter\n");
296 ERR("General error");