2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include "notification-ex/dbus_connection_manager.h"
25 #include "notification-ex/dbus_event_listener.h"
26 #include "notification-ex/dbus_event_listener_implementation.h"
27 #include "notification-ex/exception.h"
28 #include "notification-ex/ex_util.h"
29 #include "notification-ex/event_info_internal.h"
35 #define LOG_TAG "NOTIFICATION_EX"
36 #define MAX_PACKAGE_STR_SIZE 512
39 using namespace tizen_base;
41 namespace notification {
43 DBusEventListener::DBusEventListener(string path)
44 : impl_(new Impl(this, path)) {
45 LOGW("Created (%s)", path.c_str());
48 DBusEventListener::~DBusEventListener() {
52 DBusEventListener::Impl::~Impl() = default;
54 DBusEventListener::Impl::Impl(DBusEventListener* parent, string path)
55 : subscribe_id_(0), registration_id_(0), path_(path), parent_(parent) {
56 LOGI("Dbus_event_listener impl created");
59 void DBusEventListener::Impl::SignalCb(GDBusConnection* connection,
60 const gchar* sender_name,
61 const gchar* object_path,
62 const gchar* interface_name,
63 const gchar* signal_name,
66 DBusEventListener::Impl* dl = static_cast<DBusEventListener::Impl*>(user_data);
67 char* appid = nullptr;
68 GVariantIter *iter = nullptr;
69 char* event_info_raw = nullptr;
70 g_variant_get(parameters, "(ssa(s))", &appid, &event_info_raw, &iter);
72 LOGI("signal callback!! (%s)", appid);
73 string sender_appid = string(appid);
74 string cur_appid = util::GetAppId();
75 if (sender_appid == cur_appid)
77 if ((!DBusConnectionManager::GetInst().IsDataProviderMaster(cur_appid)
78 && !DBusConnectionManager::GetInst().IsDataProviderMaster(sender_appid))
79 || (cur_appid == sender_appid))
82 LOGE("%s : %s", cur_appid.c_str(), sender_appid.c_str());
85 list<Bundle> ret_list;
86 while (g_variant_iter_loop(iter, "(s)", &raw) && raw != nullptr) {
88 ret_list.emplace_back(ret);
91 Bundle b(event_info_raw);
93 dl->parent_->NotifyObserver(info, ret_list);
96 void DBusEventListener::Impl::OnMethodCall(
97 GDBusConnection *conn, const gchar *sender, const gchar *object_path,
98 const gchar *iface_name, const gchar *method_name,
99 GVariant *parameters, GDBusMethodInvocation *invocation,
100 gpointer user_data) {
101 LOGI("method_name[%s] sender[%s]", method_name, sender);
102 DBusEventListener::Impl* dl = static_cast<DBusEventListener::Impl*>(user_data);
103 GVariant *reply_body = NULL;
104 if (g_strcmp0(method_name, "Get") == 0) {
106 char* serialized = NULL;
107 g_variant_get(parameters, "(&s&s)", &appid, &serialized);
109 Bundle b(serialized);
111 list<Bundle> result = dl->parent_->NotifyObserver(info);
112 GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
113 for (auto& i : result) {
114 g_variant_builder_add(builder, "(s)",
115 reinterpret_cast<char*>(i.ToRaw().first.get()));
117 reply_body = g_variant_new("(a(s))", builder);
118 g_variant_builder_unref(builder);
119 } else if (g_strcmp0(method_name, "Count") == 0) {
121 char* serialized = NULL;
122 g_variant_get(parameters, "(&s&s)", &appid, &serialized);
124 Bundle b(serialized);
126 int num = dl->parent_->NotifyNumberRequest(info);
127 reply_body = g_variant_new("(i)", num);
129 g_dbus_method_invocation_return_value(invocation, reply_body);
132 int DBusEventListener::Impl::RegisterGDBusInterface() {
133 static const GDBusInterfaceVTable interface_vtable = {
138 static gchar introspection_xml[] =
140 " <interface name='org.tizen.notification_ex'>"
141 " <method name='Get'>"
142 " <arg type='s' name='appid' direction='in'/>"
143 " <arg type='s' name='serialized' direction='in'/>"
144 " <arg type='a(s)' name='noti_arr' direction='out'/>"
146 " <method name='Count'>"
147 " <arg type='s' name='appid' direction='in'/>"
148 " <arg type='s' name='serialized' direction='in'/>"
149 " <arg type='i' name='num' direction='out'/>"
153 GError *error = NULL;
154 GDBusNodeInfo *introspection_data =
155 g_dbus_node_info_new_for_xml(introspection_xml, &error);
156 if (!introspection_data) {
157 LOGE("g_dbus_node_info_new_for_xml is failed.");
159 LOGE("g_dbus_node_info_new_for_xml err [%s]", error->message);
162 return ERROR_IO_ERROR;
165 registration_id_ = g_dbus_connection_register_object(
166 DBusConnectionManager::GetInst().GetConnection(),
167 path_.c_str(), introspection_data->interfaces[0],
168 &interface_vtable, this, NULL, NULL);
169 g_dbus_node_info_unref(introspection_data);
170 if (registration_id_ == 0) {
171 LOGE("register object fail");
172 return ERROR_IO_ERROR;
175 LOGI("RegisterGDBusInterface success");
179 void DBusEventListener::Impl::UnRegisterGDBusInterface() {
180 g_dbus_connection_unregister_object(
181 DBusConnectionManager::GetInst().GetConnection(),
185 bool DBusEventListener::Impl::SubscribeSignal() {
186 subscribe_id_ = g_dbus_connection_signal_subscribe(
187 DBusConnectionManager::GetInst().GetConnection(),
189 DBusConnectionManager::GetInst().GetInterfaceName().c_str(),
193 G_DBUS_SIGNAL_FLAGS_NONE,
197 return subscribe_id_ > 0;
200 void DBusEventListener::Impl::UnSubscribeSignal() {
201 g_dbus_connection_signal_unsubscribe(
202 DBusConnectionManager::GetInst().GetConnection(), subscribe_id_);
206 void DBusEventListener::RegisterObserver(IEventObserver* observer) {
207 if (impl_->subscribe_id_ == 0) {
208 impl_->SubscribeSignal();
210 impl_->UnSubscribeSignal();
211 impl_->SubscribeSignal();
214 if (impl_->registration_id_ == 0) {
215 impl_->RegisterGDBusInterface();
217 impl_->UnRegisterGDBusInterface();
218 impl_->RegisterGDBusInterface();
220 impl_->observer_ = observer;
223 void DBusEventListener::UnRegisterObserver(IEventObserver* observer) {
224 impl_->UnSubscribeSignal();
225 impl_->observer_ = NULL;
228 void DBusEventListener::NotifyObserver(
229 const IEventInfo& info, list<Bundle> serialized) {
230 impl_->observer_->OnEvent(info, serialized);
233 list<Bundle> DBusEventListener::NotifyObserver(const IEventInfo& info) {
234 return impl_->observer_->OnRequest(info);
237 int DBusEventListener::NotifyNumberRequest(const IEventInfo& info) {
238 return impl_->observer_->OnRequestNumber(info);
241 } // namespace notification