Remove event after using to prevent leak
[platform/core/appfw/data-provider-master.git] / src / service_common.cc
1 /*
2 * Copyright 2023 Samsung Electronics Co., Ltd
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #include <gio/gio.h>
22 #include <dlog.h>
23 #include <notification_setting.h>
24 #include <notification_setting_internal.h>
25 #include <notification_setting_service.h>
26 #include <notification_noti.h>
27 #include <badge_setting.h>
28 #include <badge_setting_service.h>
29 #include <badge_db.h>
30 #include <package-manager.h>
31 #include <tzplatform_config.h>
32 #include <pkgmgr-info.h>
33
34 #include <list>
35 #include <set>
36 #include <string>
37 #include <string_view>
38 #include <memory>
39
40 #include "debug.h"
41 #include "pkgmgr_client.hh"
42 #include "service_common.h"
43 #include "notification_service.h"
44 #include "badge_service.h"
45 #include "shortcut_service.h"
46
47 #define DBUS_NAME "org.freedesktop.DBus"
48 #define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
49 #define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
50
51 #define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
52 #define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
53
54 using namespace dpm;
55
56 static GDBusConnection *_gdbus_conn;
57 static GHashTable *_noti_pkg_privilege_info;
58 static GHashTable *_badge_pkg_privilege_info;
59 std::unique_ptr<PkgmgrClient> pkgmgr_client_;
60 std::list<std::shared_ptr<PkgmgrEventArgs>> pkgmgr_event_list_;
61 std::list<std::shared_ptr<PkgmgrAppEventArgs>> pkgmgr_app_event_list_;
62
63 const std::set<std::string_view> pkgmgr_installer_key_list_ = {
64   "install_percent",
65   "start",
66   "end"
67 };
68
69 const std::set<std::string_view> pkgmgr_installer_val_list_ = {
70   "install",
71   "uninstall",
72   "update",
73   "ebable_app",
74   "disable_app"
75 };
76
77 static int _package_install_cb(uid_t uid, const char *pkgname);
78 static int _package_uninstall_cb(uid_t uid, const char *pkgname);
79 static int _app_enabled_cb(uid_t uid, const char *app_id);
80 static int _app_disabled_cb(uid_t uid, const char *app_id);
81
82 class PackageEventListener : public PkgmgrClient::IEvent {
83 public:
84   void OnPkgmgrEvent(std::shared_ptr<PkgmgrEventArgs> args) override;
85   void OnPkgmgrAppEvent(std::shared_ptr<PkgmgrAppEventArgs> args) override;
86 };
87
88 void PackageEventListener::OnPkgmgrEvent(std::shared_ptr<PkgmgrEventArgs> args) {
89   if (pkgmgr_installer_key_list_.find(args->GetEventStatus()) ==
90       pkgmgr_installer_key_list_.end())
91     return;
92
93   if (args->GetEventStatus().compare(std::string("start")) == 0 &&
94       pkgmgr_installer_val_list_.find(args->GetEventName()) !=
95       pkgmgr_installer_val_list_.end()) {
96     pkgmgr_event_list_.push_back(args);
97     return;
98   }
99
100   if (args->GetEventName().compare(std::string("ok")) == 0) {
101     auto iter = pkgmgr_event_list_.begin();
102     while(iter != pkgmgr_event_list_.end()) {
103       if ((*iter)->GetTargetUid() == args->GetTargetUid() &&
104           (*iter)->GetPkgId().compare(args->GetPkgId()) == 0) {
105         if ((*iter)->GetEventName().compare(std::string("install")) == 0)
106           _package_install_cb(args->GetTargetUid(), args->GetPkgId().c_str());
107         else if ((*iter)->GetEventName().compare(std::string("uninstall")) == 0)
108           _package_uninstall_cb(args->GetTargetUid(), args->GetPkgId().c_str());
109         else if ((*iter)->GetEventName().compare(std::string("enable_app")) == 0)
110           _app_enabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
111         else if ((*iter)->GetEventName().compare(std::string("disable_app")) == 0)
112           _app_disabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
113
114         iter = pkgmgr_event_list_.erase(iter);
115       } else {
116         iter++;
117       }
118     }
119   } else if (args->GetEventName().compare(std::string("fail")) == 0) {
120     auto iter = pkgmgr_event_list_.begin();
121     while(iter != pkgmgr_event_list_.end()) {
122       if ((*iter)->GetTargetUid() == args->GetTargetUid() &&
123           (*iter)->GetPkgId().compare(args->GetPkgId()) == 0) {
124         iter = pkgmgr_event_list_.erase(iter);
125       } else {
126         iter++;
127       }
128     }
129   }
130 }
131
132 void PackageEventListener::OnPkgmgrAppEvent(std::shared_ptr<PkgmgrAppEventArgs> args) {
133   if (pkgmgr_installer_key_list_.find(args->GetEventStatus()) ==
134       pkgmgr_installer_key_list_.end())
135     return;
136
137   if (args->GetEventStatus().compare(std::string("start")) == 0 &&
138       pkgmgr_installer_val_list_.find(args->GetEventName()) !=
139       pkgmgr_installer_val_list_.end()) {
140     pkgmgr_app_event_list_.push_back(args);
141     return;
142   }
143
144   if (args->GetEventName().compare(std::string("ok")) == 0) {
145     auto iter = pkgmgr_app_event_list_.begin();
146     while(iter != pkgmgr_app_event_list_.end()) {
147       if ((*iter)->GetTargetUid() == args->GetTargetUid() &&
148           (*iter)->GetPkgId().compare(args->GetPkgId()) == 0) {
149         if ((*iter)->GetEventName().compare(std::string("install")) == 0)
150           _package_install_cb(args->GetTargetUid(), args->GetPkgId().c_str());
151         else if ((*iter)->GetEventName().compare(std::string("uninstall")) == 0)
152           _package_uninstall_cb(args->GetTargetUid(), args->GetPkgId().c_str());
153         else if ((*iter)->GetEventName().compare(std::string("enable_app")) == 0)
154           _app_enabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
155         else if ((*iter)->GetEventName().compare(std::string("disable_app")) == 0)
156           _app_disabled_cb(args->GetTargetUid(), args->GetPkgId().c_str());
157
158         iter = pkgmgr_app_event_list_.erase(iter);
159       } else {
160         iter++;
161       }
162     }
163   } else if (args->GetEventName().compare(std::string("fail")) == 0) {
164     auto iter = pkgmgr_app_event_list_.begin();
165     while(iter != pkgmgr_app_event_list_.end()) {
166       if ((*iter)->GetTargetUid() == args->GetTargetUid() &&
167           (*iter)->GetPkgId().compare(args->GetPkgId()) == 0) {
168         iter = pkgmgr_app_event_list_.erase(iter);
169       } else {
170         iter++;
171       }
172     }
173   }
174 }
175
176 uid_t get_sender_uid(const char *sender_name) {
177   GDBusMessage *msg = nullptr;
178   GDBusMessage *reply = nullptr;
179   GError *err = nullptr;
180   GVariant *body;
181   uid_t uid = 0;
182
183   msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
184       DBUS_INTERFACE_NAME, "GetConnectionUnixUser");
185   if (!msg) {
186     LOGE("Failed to alloc new method call");
187     goto out;
188   }
189
190   g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
191   reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
192       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
193
194   if (!reply) {
195     if (err != nullptr) {
196       LOGE("Failed to get uid [%s]", err->message);
197       g_error_free(err);
198     }
199     goto out;
200   }
201
202   body = g_dbus_message_get_body(reply);
203   g_variant_get(body, "(u)", &uid);
204
205 out:
206   if (msg)
207     g_object_unref(msg);
208   if (reply)
209     g_object_unref(reply);
210
211   return uid;
212 }
213
214 pid_t get_sender_pid(const char *sender_name) {
215   GDBusMessage *msg = nullptr;
216   GDBusMessage *reply = nullptr;
217   GError *err = nullptr;
218   GVariant *body;
219   pid_t pid = 0;
220
221   msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
222       DBUS_INTERFACE_NAME, "GetConnectionUnixProcessID");
223   if (!msg) {
224     LOGE("Failed to alloc new method call");
225     goto out;
226   }
227
228   g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
229   reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
230       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
231
232   if (!reply) {
233     if (err != nullptr) {
234       LOGE("Failed to get uid [%s]", err->message);
235       g_error_free(err);
236     }
237     goto out;
238   }
239
240   body = g_dbus_message_get_body(reply);
241   g_variant_get(body, "(u)", &pid);
242
243 out:
244   if (msg)
245     g_object_unref(msg);
246   if (reply)
247     g_object_unref(reply);
248
249   return pid;
250 }
251
252 bool is_existed_busname(const char *sender_name) {
253   GDBusMessage *msg = nullptr;
254   GDBusMessage *reply = nullptr;
255   GError *err = nullptr;
256   GVariant *body;
257   bool is_existed = false;
258
259   msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
260       DBUS_INTERFACE_NAME, "NameHasOwner");
261   if (!msg) {
262     LOGE("Failed to alloc new method call");
263     goto out;
264   }
265
266   g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
267   reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
268       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
269
270   if (!reply) {
271     if (err != nullptr) {
272       LOGE("Failed to get uid [%s]", err->message);
273       g_error_free(err);
274     }
275     goto out;
276   }
277
278   body = g_dbus_message_get_body(reply);
279   g_variant_get(body, "(b)", &is_existed);
280
281 out:
282   if (msg)
283     g_object_unref(msg);
284   if (reply)
285     g_object_unref(reply);
286
287   return is_existed;
288 }
289
290 int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash,
291     char *interface_name, uid_t uid) {
292   GError *err = nullptr;
293   GList *monitoring_list = nullptr;
294   GList *target_list;
295   char *target_bus_name;
296   int monitoring_count = 0;
297   bool is_existed = false;
298
299   monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
300   target_list = g_list_first(monitoring_list);
301   for (; target_list != nullptr; ) {
302     err = nullptr;
303     target_bus_name = static_cast<char*>(target_list->data);
304     target_list = target_list->next;
305
306     if (g_variant_is_floating(body))
307       g_variant_ref(body);
308
309     if (g_dbus_connection_emit_signal(_gdbus_conn,
310           target_bus_name,
311           PROVIDER_OBJECT_PATH,
312           interface_name,
313           cmd,
314           body,
315           &err) == FALSE) {
316       if (err != nullptr) {
317         ERR("Emit signal err [%s]", err->message);
318         g_clear_error(&err);
319       }
320       is_existed = is_existed_busname(target_bus_name);
321       if (is_existed == false)
322         delete_monitoring_list(monitoring_hash, target_bus_name, uid);
323       ERR("Fail, emit signal to [%s]", target_bus_name);
324     }
325
326     if (g_dbus_connection_flush_sync(_gdbus_conn, NULL, &err) == FALSE) {
327       ERR("Failed to flush connection[%s]", err ? err->message : "");
328       g_clear_error(&err);
329     }
330
331     monitoring_count++;
332     WARN("Success, emit signal to [%s]", target_bus_name);
333   }
334
335   WARN("Success, cmd[%s] monitoring count[%d]", cmd, monitoring_count);
336   return SERVICE_COMMON_ERROR_NONE;
337 }
338
339 int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname,
340     char *interface_name) {
341   GError *err = nullptr;
342
343   if (g_variant_is_floating(body))
344     g_variant_ref(body);
345
346   if (g_dbus_connection_emit_signal(_gdbus_conn,
347             busname,
348             PROVIDER_OBJECT_PATH,
349             interface_name,
350             cmd,
351             body,
352             &err) == FALSE) {
353     if (err != nullptr) {
354       ERR("Emit signal err [%s]",
355           err->message);
356       g_clear_error(&err);
357     }
358     ERR("Failed to emit signal to [%s]", busname);
359     return SERVICE_COMMON_ERROR_IO_ERROR;
360   }
361
362   if (g_dbus_connection_flush_sync(_gdbus_conn, NULL, &err) == FALSE) {
363     ERR("Failed to flush connection[%s]", err ? err->message : "");
364     g_clear_error(&err);
365
366     return SERVICE_COMMON_ERROR_IO_ERROR;
367   }
368
369   WARN("Success, Emit signal to [%s] cmd[%s]", busname, cmd);
370   return SERVICE_COMMON_ERROR_NONE;
371 }
372
373 /* register service */
374
375 static int _monitoring_app_list_compare_cb(gconstpointer a, gconstpointer b) {
376   return strcmp(static_cast<const char*>(a), reinterpret_cast<const char*>(b));
377 }
378
379 int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
380     GBusNameAppearedCallback name_appeared_handler,
381     GBusNameVanishedCallback name_vanished_handler,
382     GHashTable **monitoring_hash,
383     uid_t uid) {
384   GList *added_list = nullptr;
385   const char *bus_name = sender;
386   monitoring_info_s *m_info = nullptr;
387   uid_t request_uid = 0;
388   GList *monitoring_list = nullptr;
389
390   if (sender == nullptr)
391     return SERVICE_COMMON_ERROR_IO_ERROR;
392
393   g_variant_get(parameters, "(i)", &request_uid);
394   if (uid > NORMAL_UID_BASE && uid != request_uid)
395     return SERVICE_COMMON_ERROR_IO_ERROR;
396
397   DBG("service_register : uid %d , request_uid %d", uid, request_uid);
398   monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
399   added_list = g_list_find_custom(monitoring_list, bus_name,
400       (GCompareFunc)_monitoring_app_list_compare_cb);
401
402   if (added_list == nullptr) {
403     DBG("add new sender to list");
404     m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
405     if (m_info == nullptr) {
406       ERR("Failed to alloc memory");
407       return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
408     }
409
410     m_info->bus_name = strdup(bus_name);
411     m_info->uid = request_uid;
412     m_info->watcher_id = g_bus_watch_name_on_connection(
413         _gdbus_conn,
414         bus_name,
415         G_BUS_NAME_WATCHER_FLAGS_NONE,
416         name_appeared_handler,
417         name_vanished_handler,
418         m_info,
419         nullptr);
420     if (m_info->watcher_id == 0) {
421       ERR("Fail to watch name [%s]", bus_name);
422       free(m_info->bus_name);
423       free(m_info);
424       return SERVICE_COMMON_ERROR_IO_ERROR;
425     }
426     DBG("Watch on [%s] success", bus_name);
427
428     monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
429     DBG("Success, sender[%s] length[%d]",
430         sender, g_list_length(monitoring_list));
431     if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == nullptr)
432       g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
433   } else {
434     ERR("Sender [%s] already exist", sender);
435   }
436
437   *reply_body = g_variant_new("()");
438   if (*reply_body == nullptr) {
439     if (m_info) {
440       if (m_info->bus_name)
441         free(m_info->bus_name);
442       free(m_info);
443     }
444     monitoring_list = g_list_remove(monitoring_list, bus_name);
445     ERR("Failed to make reply");
446     return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
447   }
448   return SERVICE_COMMON_ERROR_NONE;
449 }
450
451 int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender,
452     uid_t uid) {
453   GList *monitoring_list = nullptr;
454   GList *del_list = nullptr;
455   char *bus_name;
456
457   monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
458   if (monitoring_list == nullptr) {
459     ERR("No uid[%d] in monitoring hash", uid);
460     return SERVICE_COMMON_ERROR_IO_ERROR;
461   }
462
463   monitoring_list = g_list_first(monitoring_list);
464   del_list = g_list_find_custom(monitoring_list, sender,
465       (GCompareFunc)_monitoring_app_list_compare_cb);
466
467   if (del_list) {
468     DBG("Find delete list - uid[%d] sender[%s]", uid, sender);
469     bus_name = static_cast<char*>(g_list_nth_data(del_list, 0));
470     if (bus_name)
471       free(bus_name);
472     monitoring_list = g_list_delete_link(monitoring_list, del_list);
473
474     if (monitoring_list == nullptr) {
475       g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
476     } else {
477       monitoring_list = g_list_first(monitoring_list);
478       g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
479     }
480   }
481   return SERVICE_COMMON_ERROR_NONE;
482 }
483
484 static int _dbus_init(void) {
485   GError *error = nullptr;
486
487   if (_gdbus_conn == nullptr) {
488     _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
489     if (_gdbus_conn == nullptr) {
490       if (error != nullptr) {
491         ERR("Failed to get dbus [%s]", error->message);
492         g_error_free(error);
493       }
494       return SERVICE_COMMON_ERROR_IO_ERROR;
495     }
496   }
497
498   return SERVICE_COMMON_ERROR_NONE;
499 }
500
501 int service_common_register_dbus_interface(char *introspection_xml,
502     GDBusInterfaceVTable interface_vtable) {
503   int result;
504   int owner_id, noti_registration_id;
505   GError *error = nullptr;
506   GDBusNodeInfo *introspection_data = nullptr;
507
508   result = _dbus_init();
509   if (result != SERVICE_COMMON_ERROR_NONE) {
510       ERR("Can't init dbus [%d]", result);
511       result = SERVICE_COMMON_ERROR_IO_ERROR;
512       goto out;
513   }
514
515   owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
516       PROVIDER_BUS_NAME,
517       G_BUS_NAME_OWNER_FLAGS_NONE,
518       nullptr,
519       nullptr,
520       nullptr,
521       nullptr, nullptr);
522   if (!owner_id) {
523     ERR("Failed to own name");
524     result = SERVICE_COMMON_ERROR_IO_ERROR;
525     goto out;
526   }
527
528   DBG("Acquiring the own name [%d]", owner_id);
529   introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
530   if (!introspection_data) {
531     ERR("g_dbus_node_info_new_for_xml is failed.");
532     result = SERVICE_COMMON_ERROR_IO_ERROR;
533     if (error != nullptr) {
534       ERR("g_dbus_node_info_new_for_xml err [%s]", error->message);
535       g_error_free(error);
536     }
537     goto out;
538   }
539
540   noti_registration_id = g_dbus_connection_register_object(_gdbus_conn,
541       PROVIDER_OBJECT_PATH, introspection_data->interfaces[0],
542       &interface_vtable, nullptr, nullptr, nullptr);
543
544   DBG("registration id[%d]", noti_registration_id);
545   if (noti_registration_id == 0) {
546     ERR("Failed to g_dbus_connection_register_object");
547     result = SERVICE_COMMON_ERROR_IO_ERROR;
548     goto out;
549   }
550
551 out:
552   if (introspection_data)
553     g_dbus_node_info_unref(introspection_data);
554
555   return result;
556 }
557
558 static int _init_pkg_privilege_info() {
559   if (_noti_pkg_privilege_info != nullptr)
560     return 0;
561
562   _noti_pkg_privilege_info =
563     g_hash_table_new_full(g_str_hash, g_str_equal, free, nullptr);
564   _badge_pkg_privilege_info =
565     g_hash_table_new_full(g_str_hash, g_str_equal, free, nullptr);
566   DBG("init pkg privilege info done");
567   return 0;
568 }
569
570 static int _package_install_cb(uid_t uid, const char *pkgname) {
571   int ret;
572   gpointer tmp;
573   int privilege_info;
574
575   if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
576     uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
577
578   _init_pkg_privilege_info();
579   if (g_hash_table_contains(_noti_pkg_privilege_info, pkgname)) {
580     tmp = g_hash_table_lookup(_noti_pkg_privilege_info, pkgname);
581     privilege_info = GPOINTER_TO_UINT(tmp);
582     if (privilege_info == 1)
583       notification_setting_db_update_pkg_disabled(pkgname, false, uid);
584
585     g_hash_table_remove(_noti_pkg_privilege_info, pkgname);
586   } else {
587     /* In consideration of the reboot status, change the disable information. */
588     ret = notification_setting_db_update_pkg_disabled(pkgname, false, uid);
589     if (ret != NOTIFICATION_ERROR_NONE)
590       notification_setting_insert_package_for_uid(pkgname, uid);
591   }
592
593   if (g_hash_table_contains(_badge_pkg_privilege_info, pkgname)) {
594     tmp = g_hash_table_lookup(_badge_pkg_privilege_info, pkgname);
595     privilege_info = GPOINTER_TO_UINT(tmp);
596     if (privilege_info == 1)
597       badge_db_update_pkg_disabled(pkgname, false, uid);
598
599     g_hash_table_remove(_badge_pkg_privilege_info, pkgname);
600   } else {
601     /* In consideration of the reboot status, change the disable information. */
602     ret = badge_db_update_pkg_disabled(pkgname, false, uid);
603     if (ret != BADGE_ERROR_NONE)
604       badge_setting_insert_package_for_uid(pkgname, uid);
605   }
606
607   return 0;
608 }
609
610 static int _package_uninstall_cb(uid_t uid, const char *pkgname) {
611   int ret;
612   pkgmgrinfo_pkginfo_h pkginfo;
613
614   if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
615     uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
616
617   ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgname, uid, &pkginfo);
618   if (ret == PMINFO_R_OK) {
619     pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
620
621     _init_pkg_privilege_info();
622     ret = notification_setting_db_update_pkg_disabled(pkgname, true, uid);
623     if (ret == NOTIFICATION_ERROR_NONE)
624       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
625     else
626       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
627
628     ret = badge_db_update_pkg_disabled(pkgname, true, uid);
629     if (ret == BADGE_ERROR_NONE)
630       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
631     else
632       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
633   } else {
634     notification_setting_delete_package_for_uid(pkgname, uid);
635     badge_db_delete_by_pkgname(pkgname, uid);
636     badge_setting_delete_package_for_uid(pkgname, uid);
637     notification_noti_delete_template(pkgname);
638   }
639
640   return 0;
641 }
642
643 static int _app_enabled_cb(uid_t uid, const char *app_id) {
644   notification_setting_db_update_app_disabled(app_id, false, uid);
645   return 0;
646 }
647
648 static int _app_disabled_cb(uid_t uid, const char *app_id) {
649   notification_delete_noti_by_app_id(app_id, uid);
650   notification_setting_db_update_app_disabled(app_id, true, uid);
651   return 0;
652 }
653
654 std::unique_ptr<PackageEventListener> listener_;
655
656 void service_common_init(void) {
657   pkgmgr_client_ = std::make_unique<PkgmgrClient>();
658   listener_ = std::make_unique<PackageEventListener>();
659   pkgmgr_client_->Listen(listener_.get());
660 }
661
662 void service_common_set_connection(GDBusConnection *conn) {
663   _gdbus_conn = conn;
664 }