Fix crash when invalid parameter given
[platform/core/api/capability-manager.git] / src / dbus.cc
1 // Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "src/dbus.h"
6 #include "src/dbus_signal.h"
7
8 #include <glib.h>
9 #include <gio/gio.h>
10
11 #include "src/utils/logging.h"
12
13 namespace {
14
15 const char kDBusServiceName[] = "org.tizen.capmgr";
16 const char kDBusObjectPath[] = "/org/tizen/capmgr";
17 const char kDBusInterfaceName[] = "org.tizen.capmgr";
18
19 struct cbdata {
20   capmgr::DBusCallback cb;
21   void* user_data;
22 };
23
24 void MethodCallback(GObject* source_object, GAsyncResult* res,
25     gpointer user_data) {
26   LOG(DEBUG) << "Got a response from capmgr";
27   GDBusProxy* proxy = reinterpret_cast<GDBusProxy*>(source_object);
28   GError* error = nullptr;
29   GVariant* result = g_dbus_proxy_call_finish(proxy, res, &error);
30
31   if (error) {
32     LOG(ERROR) << "g_dbus_proxy_call_finish() failed: " << error->message;
33     return;
34   }
35
36   struct cbdata* cbdata = reinterpret_cast<struct cbdata*>(user_data);
37   cbdata->cb(result, cbdata->user_data);
38   delete cbdata;
39 }
40
41 void SignalCallback(GDBusProxy* proxy, gchar* sender_name, gchar* signal_name,
42     GVariant* parameters, gpointer user_data) {
43   capmgr::DBusSignal* ds = reinterpret_cast<capmgr::DBusSignal*>(user_data);
44
45   LOG(INFO) << "Signal recieved " << signal_name;
46   if (g_strcmp0(ds->GetSignalName(), signal_name) == 0) {
47     LOG(INFO) << "progress callback called";
48     ds->Emit(parameters);
49   }
50 }
51
52 bool InitDBusProxy(GDBusConnection** connection, GDBusProxy** proxy) {
53   GError* error = nullptr;
54   GDBusConnection* conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
55   if (!conn) {
56     LOG(ERROR) << "g_bus_get_sync() failed: " << error->message;
57     g_object_unref(error);
58     return false;
59   }
60
61   GDBusProxy* p = g_dbus_proxy_new_sync(conn,
62       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, nullptr,
63       kDBusServiceName, kDBusObjectPath, kDBusInterfaceName, nullptr,
64       &error);
65   if (!p) {
66     LOG(ERROR) << "g_dbus_proxy_new_sync() failed: " << error->message;
67     g_object_unref(error);
68     g_object_unref(conn);
69     return false;
70   }
71
72   *connection = conn;
73   *proxy = p;
74   return true;
75 }
76
77 void DisposeDBusProxy(GDBusConnection* conn, GDBusProxy* proxy) {
78   if (proxy)
79     g_object_unref(proxy);
80   if (conn) {
81     g_dbus_connection_flush_sync(conn, nullptr, nullptr);
82     g_object_unref(conn);
83   }
84 }
85
86 }  // namespace
87
88 namespace capmgr {
89
90 DBusSignal::DBusSignal(const std::string& signal_name)
91     : signal_name_ { signal_name } {}
92
93 DBusSignal::~DBusSignal() {
94   DisposeDBusProxy(this->conn_, this->proxy_);
95 }
96
97 void DBusSignal::RegisterHandler(DBusCallback cb, void* user_data) {
98   this->cb_ = cb;
99   this->user_data_ = user_data;
100 }
101
102 void DBusSignal::Emit(GVariant* param) {
103   this->cb_(param, this->user_data_);
104 }
105
106 bool DBusSignal::Subscribe() {
107   if (!InitDBusProxy(&this->conn_, &this->proxy_)) {
108     LOG(ERROR) << "DBus initilization failed";
109     return false;
110   }
111
112   g_signal_connect(this->proxy_, "g-signal", G_CALLBACK(SignalCallback), this);
113
114   return true;
115 }
116
117 const char* DBusSignal::GetSignalName() {
118   return this->signal_name_.c_str();
119 }
120
121 bool ProxyCallAsync(const char* method, GVariant* params, DBusCallback cb,
122     void* user_data) {
123   GDBusConnection* conn = nullptr;
124   GDBusProxy* proxy = nullptr;
125
126   if (!InitDBusProxy(&conn, &proxy)) {
127     LOG(ERROR) << "DBus initilization failed";
128     return false;
129   }
130
131   // will be freed at MethodCallback()
132   struct cbdata* cbdata = new struct cbdata();
133   cbdata->cb = cb;
134   cbdata->user_data = user_data;
135
136   g_dbus_proxy_call(proxy, method,
137       params, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, MethodCallback, cbdata);
138
139   DisposeDBusProxy(conn, proxy);
140
141   return true;
142 }
143
144 }  // namespace capmgr