2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
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.
17 #include "db_change_observer.hh"
19 #include <tzplatform_config.h>
23 #include "utils/logging.hh"
25 #include "pkgmgrinfo_debug.h"
26 #include "pkgmgr-info.h"
29 #define LOG_TAG "PKGMGR_INFO"
33 uid_t globaluser_uid = -1;
35 uid_t GetGlobalUID() {
36 if (globaluser_uid == (uid_t)-1)
37 globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
39 return globaluser_uid;
44 namespace pkgmgr_common {
46 DbChangeObserver& DbChangeObserver::GetInst() {
47 static DbChangeObserver inst;
52 gboolean DbChangeObserver::OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
54 LOG(WARNING) << "db changed event occured";
55 char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
56 auto db_change = reinterpret_cast<DbChangeObserver*>(user_data);
57 int fd = g_io_channel_unix_get_fd(channel);
59 while(read(fd, buf, sizeof(buf)) > 0);
61 std::unique_lock<std::shared_mutex> u(db_change->lock_);
62 if (!db_change->changed_) {
63 db_change->changed_ = true;
64 if (db_change->listener_)
65 db_change->listener_->OnDbChanged();
68 return G_SOURCE_CONTINUE;
71 DbChangeObserver::DbChangeObserver() {
72 std::unique_lock<std::shared_mutex> u(lock_);
73 SetGlobalParserDbPath();
76 DbChangeObserver::~DbChangeObserver() {
77 std::unique_lock<std::shared_mutex> u(lock_);
81 bool DbChangeObserver::Listen() {
82 std::unique_lock<std::shared_mutex> u(lock_);
87 if (global_parser_db_path_.empty()) {
88 if (!SetGlobalParserDbPath()) {
89 LOG(ERROR) << "Fail to Set GlobalParserDbPath";
96 fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
98 LOG(ERROR) << "Failed to inotify_init. errno: " << errno;
103 wd_ = inotify_add_watch(fd_, global_parser_db_path_.c_str(), IN_MODIFY);
105 LOG(ERROR) << "Failed to inotify_add_watch. errno: " << errno;
110 channel_ = g_io_channel_unix_new(fd_);
111 if (channel_ == nullptr) {
112 LOG(ERROR) << "Failed to create GIO channel";
117 tag_ = g_io_add_watch(channel_, (GIOCondition)(G_IO_IN), OnReceiveEvent, this);
119 LOG(ERROR) << "Failed to add watch";
130 void DbChangeObserver::StopListening() {
131 std::unique_lock<std::shared_mutex> u(lock_);
136 bool DbChangeObserver::IsChanged() {
137 std::shared_lock<std::shared_mutex> s(lock_);
141 void DbChangeObserver::SetChanged(bool changed) {
142 std::unique_lock<std::shared_mutex>s (lock_);
146 void DbChangeObserver::Dispose() {
151 g_source_remove(tag_);
155 if (channel_ != nullptr) {
156 g_io_channel_unref(channel_);
161 inotify_rm_watch(fd_, wd_);
173 bool DbChangeObserver::GetDisposed() {
174 std::shared_lock<std::shared_mutex> s(lock_);
179 bool DbChangeObserver::SetGlobalParserDbPath() {
180 char* tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
181 if (tmp_path == nullptr) {
182 LOG(ERROR) << "Fail to global parser db";
185 global_parser_db_path_ = tmp_path;
190 void DbChangeObserver::RegisterEvent(IEvent* listener) {
191 std::unique_lock<std::shared_mutex> s(lock_);
192 listener_ = listener;
195 void DbChangeObserver::UnRegisterEvent() {
196 std::unique_lock<std::shared_mutex> s(lock_);
200 } // namespace pkgmgr_common