static const std::string APP_SHM_PREFIX = ".pkgmgr_info_app_";
-inline bool CheckPrivilegeFilters(const char* pkgid, uid_t uid,
+inline bool CheckPrivilegeFilters(const PkgInfoHandle& p_handle,
const std::unordered_set<std::string>& privilege_filters) {
- ShmPkgReader pkg_reader(uid);
-
- auto pkg_info = pkg_reader.GetHandle(pkgid);
- if (!pkg_info)
- return false;
-
- for (const auto priv : pkg_info->GetPrivileges()) {
+ for (const auto priv : p_handle.GetPrivileges()) {
if (priv.Value() != nullptr && privilege_filters.count(priv.Value()))
return true;
}
}
}
} else {
- for (auto& reader : readers_) {
- ShmError result;
- auto handles = reader->GetHandles(&result);
- if (!handles && result != ShmError::NONE)
- return PMINFO_R_ERROR;
+ if (!filter_checker.HasPrivilegeFilter()) {
+ for (auto& reader : readers_) {
+ ShmError result;
+ auto handles = reader->GetHandles(&result);
+ if (!handles && result != ShmError::NONE)
+ return PMINFO_R_ERROR;
- if (!handles)
- continue;
+ if (!handles)
+ continue;
- for (auto& handle : *handles)
- if (filter_checker.Check(handle))
- list.emplace(handle.GetAppId(), std::move(handle));
+ for (const auto& [_ , handle] : handles->GetMap())
+ if (filter_checker.Check(handle))
+ list.emplace(handle.GetAppId(), handle.Clone());
+ }
+ } else {
+ std::vector<ShmReader<PkgInfoHandle>*> pkg_readers;
+ pkg_readers.emplace_back(
+ ShmPkgReader::ShmPkgReaderProvider::GetReader(uid_));
+ if (uid_ > REGULAR_USER)
+ pkg_readers.emplace_back(
+ ShmPkgReader::ShmPkgReaderProvider::GetReader(GLOBAL_USER));
+
+ auto app_it = readers_.begin();
+ auto pkg_it = pkg_readers.begin();
+
+ while (app_it != readers_.end() && pkg_it != pkg_readers.end()) {
+ auto pkg_lock = (*pkg_it)->GetLock();
+ auto app_lock = (*app_it)->GetLock();
+
+ if (!pkg_lock || !app_lock) {
+ LOGW("Failed to get lock");
+ return PMINFO_R_ERROR;
+ }
+
+ ShmError result;
+ auto app_handles = (*app_it)->GetHandles(&result);
+ if (!app_handles && result != ShmError::NONE)
+ return PMINFO_R_ERROR;
+
+ if (!app_handles) {
+ app_it++;
+ pkg_it++;
+ continue;
+ }
+
+ auto pkg_handles = (*pkg_it)->GetHandles(&result);
+ if (!pkg_handles && result != ShmError::NONE)
+ return PMINFO_R_ERROR;
+
+ pkg_lock->Unlock();
+ app_lock->Unlock();
+
+
+ const auto& pkg_maps = pkg_handles->GetMap();
+ for (const auto& [_ , a_handle] : app_handles->GetMap()) {
+ auto pkg_it = pkg_maps.find(a_handle.GetPackage());
+ if (pkg_it == pkg_maps.end())
+ continue;
+
+ if (filter_checker.Check(a_handle) &&
+ filter_checker.CheckPrivilege(pkg_it->second))
+ list.emplace(a_handle.GetAppId(), a_handle.Clone());
+ }
+
+ app_it++;
+ pkg_it++;
+ }
}
}
if (!metadata_map_.empty() && !CheckMetadataFilter(&handle, metadata_map_))
return false;
- if (!privilege_filters_.empty() &&
- !CheckPrivilegeFilters(handle.GetPackage(), uid_, privilege_filters_))
- return false;
-
for (auto [checker, value] : filter_checker_)
if (!checker->CheckFilter(value, &handle))
return false;
return true;
}
+bool ShmAppReader::FilterChecker::CheckPrivilege(
+ const PkgInfoHandle& p_handle) {
+ if (!CheckPrivilegeFilters(p_handle, privilege_filters_))
+ return false;
+
+ return true;
+}
+
const char* ShmAppReader::FilterChecker::AppIdFilterValue() {
return appid_filter_;
}
+bool ShmAppReader::FilterChecker::HasPrivilegeFilter() {
+ return !privilege_filters_.empty();
+}
+
ShmReader<AppInfoHandle>*
ShmAppReader::ShmAppReaderProvider::GetReader(uid_t uid) {
static std::shared_mutex lock_;
FilterChecker(uid_t uid);
bool Init(pkgmgrinfo_filter_x* filter);
bool Check(const AppInfoHandle& handle);
+ bool CheckPrivilege(const PkgInfoHandle& p_handle);
const char* AppIdFilterValue();
+ bool HasPrivilegeFilter();
private:
uid_t uid_;
if (!handles)
continue;
- for (auto& handle : *handles)
+ for (const auto& [_ , handle] : handles->GetMap())
if (filter_checker.Check(handle))
- list.emplace(handle.GetPackage(), std::move(handle));
+ list.emplace(handle.GetPackage(), handle.Clone());
}
}
class EXPORT_API ShmPkgReader {
public:
+ class EXPORT_API ShmPkgReaderProvider {
+ public:
+ ShmPkgReaderProvider() = delete;
+
+ static ShmReader<PkgInfoHandle>* GetReader(uid_t uid);
+
+ private:
+ static inline std::unordered_map<uid_t,
+ ShmReader<PkgInfoHandle>*> readers_map_;
+ };
+
ShmPkgReader(uid_t uid);
int GetHandles(pkgmgrinfo_filter_x* filter,
std::vector<std::pair<IPkgFilterChecker*, const char*>> filter_checker_;
};
- class EXPORT_API ShmPkgReaderProvider {
- public:
- ShmPkgReaderProvider() = delete;
-
- static ShmReader<PkgInfoHandle>* GetReader(uid_t uid);
-
- private:
- static inline std::unordered_map<uid_t,
- ShmReader<PkgInfoHandle>*> readers_map_;
- };
-
private:
std::vector<ShmReader<PkgInfoHandle>*> readers_;
};
}
template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::GetHandles(ShmError* result) {
+std::optional<typename ShmReader<T>::HandleCollection> ShmReader<T>::GetHandles(ShmError* result) {
std::shared_lock<std::shared_mutex> s(lock_);
auto lock = Load(result, s);
if (!lock)
}
template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::ReadHandles(ShmError* result) {
+std::optional<ShmLockGuard> ShmReader<T>::GetLock() {
+ std::shared_lock<std::shared_mutex> s(lock_);
+ ShmError result;
+ auto lock = Load(&result, s);
+ if (!lock)
+ return std::nullopt;
+
+ return lock;
+}
+
+template<typename T>
+std::optional<typename ShmReader<T>::HandleCollection> ShmReader<T>::ReadHandles(ShmError* result) {
if (!result) {
LOGE("Invalid parameter");
return std::nullopt;
if (index_mapper_.GetMemSize() == 0) {
LOGD("Empty Shm Data");
- return std::vector<T>{};
+ ShmReader<T>::HandleCollection({}, {});
}
- std::vector<T> handles;
- uint8_t* ptr = handle_mapper_.GetPtr();
+ std::map<std::string, T> handles;
+ std::vector<uint8_t> data(
+ handle_mapper_.GetPtr(),
+ handle_mapper_.GetPtr() + handle_mapper_.GetMemSize());
+ uint8_t* ptr = data.data();
auto index_ptr = (HandleMappingData*)index_mapper_.GetPtr();
auto end_ptr =
(HandleMappingData*)(index_mapper_.GetPtr() + index_mapper_.GetMemSize());
- for (; index_ptr != end_ptr; index_ptr++)
- handles.emplace_back(std::make_unique<tizen_base::Parcel>(
- ptr + index_ptr->index, index_ptr->len, true));
+ for (; index_ptr != end_ptr; index_ptr++) {
+ T handle(std::make_unique<tizen_base::Parcel>(
+ ptr + index_ptr->index, index_ptr->len, false, false));
+ handles.emplace(handle.GetKey(), std::move(handle));
+ }
- return handles;
+ return ShmReader<T>::HandleCollection(std::move(data), std::move(handles));
}
template<typename T>
#include <optional>
#include <shared_mutex>
#include <vector>
+#include <map>
#include "pkgmgr_info_handle.hh"
#include "pkgmgrinfo_private.h"
template<typename T>
class EXPORT_API ShmReader {
public:
+ class HandleCollection {
+ public:
+ HandleCollection(std::vector<uint8_t> data,
+ std::map<std::string, T> handles)
+ : data_(std::move(data)), handles_(std::move(handles)) {}
+
+ const std::map<std::string, T>& GetMap() {
+ return handles_;
+ }
+
+ private:
+ std::vector<uint8_t> data_;
+ std::map<std::string, T> handles_;
+ };
+
ShmReader(std::string base_name) :
base_name_(std::move(base_name)),
config_handler_(base_name_ + "_config"),
handle_mapper_(base_name_ + "_handle"),
index_mapper_(base_name_ + "_indexs") {}
- std::optional<std::vector<T>> GetHandles(ShmError* result);
+ std::optional<HandleCollection> GetHandles(ShmError* result);
std::optional<T> GetHandle(const char* key, ShmError* result);
+ std::optional<ShmLockGuard> GetLock();
private:
std::optional<ShmLockGuard> Load(ShmError* result,
std::shared_lock<std::shared_mutex>& s);
- std::optional<std::vector<T>> ReadHandles(ShmError* result);
+ std::optional<HandleCollection> ReadHandles(ShmError* result);
std::optional<T> ReadHandle(uint32_t index, uint32_t len);
HandleMappingData* FindIndex(const char* key, ShmError* result);