#include "set_cert_request_handler.hh"
#include "set_pkginfo_request_handler.hh"
#include "system_locale.hh"
-
+#include "ready_checker.hh"
#include "pkgmgrinfo_debug.h"
namespace pkgmgr_client {
}
bool PkgInfoClient::SendRequest() {
+ static pkgmgr_common::ReadyChecker check_server(SERVER_READY);
if (socket_ == nullptr) {
LOGE("Socket is not ready");
return false;
}
- if (access(SERVER_READY, F_OK) != 0) {
+ if (!check_server.IsReady()) {
LOGW("Server is not ready, try to direct access");
is_offline_ = true;
return RequestHandlerDirectAccess();
}
AbstractDBHandler::~AbstractDBHandler() {
- for (auto db_handle : db_handle_list_)
+ for (auto& db_handle : db_handle_list_)
sqlite3_close_v2(db_handle.first);
}
auto dbpath_list = GetDBPath();
int ret = 0;
sqlite3* db;
- for (auto dbpath : dbpath_list) {
+ for (auto& dbpath : dbpath_list) {
if (op_type_ == OPERATION_TYPE_READ) {
ret = __open_read_db(dbpath.first.c_str(), &db, SQLITE_OPEN_READONLY |
SQLITE_OPEN_URI);
op_type_ = type;
}
-std::string AbstractDBHandler::GetLocale() { return locale_; }
+const std::string& AbstractDBHandler::GetLocale() { return locale_; }
int AbstractDBHandler::GetPID() { return pid_; }
-void AbstractDBHandler::SetLocale(const std::string& locale) {
- locale_ = locale;
+void AbstractDBHandler::SetLocale(std::string locale) {
+ locale_ = std::move(locale);
}
void AbstractDBHandler::SetDBType(DBType type) { db_type_ = type; }
AbstractDBHandler(uid_t uid, pid_t pid);
virtual ~AbstractDBHandler();
virtual int Execute() = 0;
- void SetLocale(const std::string& locale);
+ void SetLocale(std::string locale);
void SetDBType(DBType type);
void SetOpType(OperationType type);
OperationType GetOpType();
bool Connect();
int GetPID();
std::vector<std::pair<sqlite3*, uid_t>> GetConnection();
- std::string GetLocale();
+ const std::string& GetLocale();
static std::shared_timed_mutex lock_;
private:
std::vector<std::pair<std::string, uid_t>> GetDBPath();
NULL, __free_applications);
std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
int ret = PMINFO_R_OK;
- for (auto conn : conn_list) {
+ for (auto& conn : conn_list) {
ret = appinfo_internal_filter_get_list(conn.first, filter_, conn.second,
uid_, GetLocale().c_str(), list);
if (ret == PMINFO_R_ERROR) {
_LOGE("Failed to connect database");
return PMINFO_R_ERROR;
}
- GList *list = nullptr;
+ GList* list = nullptr;
std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
int ret = PMINFO_R_OK;
for (auto& conn : conn_list) {
break;
}
- for (GList *tmp = list; tmp; tmp = tmp->next)
+ for (GList* tmp = list; tmp; tmp = tmp->next)
dependency_list_.emplace_back(reinterpret_cast<dependency_x *>(tmp->data));
g_list_free(list);
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ready_checker.hh"
+
+#include <utility>
+
+#include "pkgmgrinfo_debug.h"
+
+#undef LOG_TAG
+#define LOG_TAG "PKGMGR_INFO"
+
+namespace pkgmgr_common {
+
+gboolean ReadyChecker::OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
+ gpointer user_data) {
+ char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
+ char* ptr;
+ ssize_t len;
+ struct inotify_event* event;
+ auto ready_checker = reinterpret_cast<ReadyChecker*>(user_data);
+ int fd = g_io_channel_unix_get_fd(channel);
+ while ((len = read(fd, buf, sizeof(buf))) > 0) {
+ for (ptr = buf; ptr < buf + len;
+ ptr += sizeof(struct inotify_event) + event->len) {
+ event = reinterpret_cast<struct inotify_event*>(ptr);
+ char* nptr = ptr + sizeof(struct inotify_event) + event->len;
+ if (nptr > buf + len)
+ break;
+
+ if (event->len) {
+ if (event->mask & IN_CREATE &&
+ ready_checker->ready_file_ == event->name) {
+ _LOGI("server is ready (%s)", ready_checker->ready_file_.c_str());
+ ready_checker->ready_ = true;
+ ready_checker->Dispose();
+ return G_SOURCE_CONTINUE;
+ }
+ }
+ }
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+ReadyChecker::ReadyChecker(const std::string& ready_path) {
+ if (access(ready_path.c_str(), F_OK) == 0) {
+ ready_ = true;
+ disposed_ = true;
+ return;
+ }
+ auto it = ready_path.find_last_of("/");
+ if (it == ready_path.npos) {
+ _LOGE("Invalid path %s", ready_path.c_str());
+ disposed_ = true;
+ return;
+ }
+
+ fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (fd_ == -1) {
+ _LOGE("Failed to inotify_init. errno(%d)", errno);
+ disposed_ = true;
+ return;
+ }
+ ready_path_ = ready_path.substr(0, it);
+ ready_file_ = ready_path.substr(it + 1);
+ wd_ = inotify_add_watch(fd_, ready_path_.c_str(), IN_CREATE);
+ if (wd_ == -1) {
+ _LOGE("Failed to inotify_add_watch. errno(%d)", errno);
+ Dispose();
+ return;
+ }
+
+ channel_ = g_io_channel_unix_new(fd_);
+ if (channel_ == nullptr) {
+ _LOGE("Failed to create GIO channel");
+ Dispose();
+ return;
+ }
+ tag_ = g_io_add_watch(channel_, G_IO_IN, OnReceiveEvent, this);
+ if (tag_ == 0) {
+ _LOGE("Failed to add watch");
+ Dispose();
+ return;
+ }
+
+ disposed_ = false;
+}
+
+ReadyChecker::~ReadyChecker() {
+ Dispose();
+}
+
+bool ReadyChecker::IsReady() const {
+ return ready_;
+}
+
+void ReadyChecker::Dispose() {
+ if (disposed_)
+ return;
+
+ if (tag_) {
+ g_source_remove(tag_);
+ tag_ = 0;
+ }
+
+ if (channel_ != nullptr) {
+ g_io_channel_unref(channel_);
+ channel_ = nullptr;
+ }
+
+ if (wd_ > 0) {
+ inotify_rm_watch(fd_, wd_);
+ wd_ = 0;
+ }
+
+ if (fd_ > 0) {
+ close(fd_);
+ fd_ = 0;
+ }
+
+ disposed_ = true;
+}
+
+} // namespace pkgmgr_common
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <sys/inotify.h>
+
+#include <string>
+
+#ifndef READY_CHECKER_HH_
+#define READY_CHECKER_HH_
+
+namespace pkgmgr_common {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API ReadyChecker {
+ public:
+ explicit ReadyChecker(const std::string& ready_path);
+ ~ReadyChecker();
+ ReadyChecker(const ReadyChecker&) = delete;
+ ReadyChecker& operator = (const ReadyChecker&) = delete;
+ bool IsReady() const;
+
+ private:
+ void Dispose();
+ static gboolean OnReceiveEvent(GIOChannel* channel, GIOCondition cond,
+ gpointer user_data);
+
+ private:
+ std::string ready_path_;
+ std::string ready_file_;
+ int fd_ = 0;
+ int wd_ = 0;
+ GIOChannel* channel_ = nullptr;
+ int tag_ = 0;
+ bool ready_ = false;
+ bool disposed_ = false;
+};
+
+} // namespace pkgmgr_common
+
+#endif // READY_CHECKER_HH_
class EXPORT_API AbstractRequestHandler {
public:
virtual ~AbstractRequestHandler() = default;
- virtual bool HandleRequest(unsigned char* data, int size, std::string locale) = 0;
+ virtual bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) = 0;
virtual std::vector<uint8_t> ExtractResult() = 0;
namespace request_handler {
bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API CommandRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool GetAppinfoRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetAppinfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool GetCertRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetCertRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool GetDepinfoRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetDepinfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool GetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetPkginfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API QueryRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API SetCertRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace request_handler {
bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
- std::string locale) {
+ const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API SetPkginfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size, std::string locale) override;
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
}
void Log(LogLevel level, const std::string& tag, const std::string& log) {
- for (auto backend : backend_list_)
+ for (auto& backend : backend_list_)
backend->WriteLog(level, tag, log);
}
#include <parcel.hh>
#include <map>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
LOG(DEBUG) << "No packages meets given condition for user " << uid;
return PMINFO_R_ENOENT;
}
- for (auto &pkginfo : result_list)
+ for (auto pkginfo : result_list)
g_hash_table_insert(packages, (gpointer)pkginfo->package,
(gpointer)pkginfo);
std::static_pointer_cast<pcp::DepInfoParcelable>(ptr));
auto dependency_list = return_parcel->ExtractDependencyInfo();
- for (auto &dependency : dependency_list)
+ for (auto dependency : dependency_list)
*dependencies = g_list_prepend(*dependencies, dependency);
return PMINFO_R_OK;
}
// result_list is vector of string vector
char* label = nullptr;
auto result_list = return_parcel->GetResult();
- for (auto result : result_list) {
+ for (auto& result : result_list) {
// result is string vector
// it only has one string or not.
- if (result.front().empty() || result.front().length() == 0)
+ if (result.front().empty())
return nullptr;
label = strdup(result.front().c_str());
if (label == nullptr) {
auto result_list = return_parcel->GetResult();
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
- if (result.size() != 2)
- return PMINFO_R_ERROR;
- if (result.front().empty() || result.front().size() == 0 ||
- result.back().empty() || result.back().size() == 0)
+ for (auto& result : result_list) {
+ if (result.size() != 2 || result.front().empty() || result.back().empty())
return PMINFO_R_ERROR;
*appid = strdup(result.front().c_str());
*access = strdup(result.back().c_str());
auto result_list = return_parcel->GetResult();
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
- if (result.size() != 1)
- return PMINFO_R_ERROR;
- if (result.front().empty() || result.front().size() == 0)
+ for (auto& result : result_list) {
+ if (result.size() != 1 || result.front().empty())
return PMINFO_R_ERROR;
*appid = strdup(result.front().c_str());
if (*appid == nullptr) {
auto result_list = return_parcel->GetResult();
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
- if (result.size() != 2)
- return PMINFO_R_ERROR;
- if (result.front().empty() || result.front().size() == 0 ||
- result.back().empty() || result.back().size() == 0)
+ for (auto& result : result_list) {
+ if (result.size() != 2 || result.front().empty() || result.back().empty())
return PMINFO_R_ERROR;
*appid = strdup(result.front().c_str());
*trusted = strdup(result.back().c_str());
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
- if (result.size() != 1)
- return PMINFO_R_ERROR;
- if (result.front().empty() || result.front().size() == 0)
+ for (auto& result : result_list) {
+ if (result.size() != 1 || result.front().empty())
return PMINFO_R_ERROR;
char* privilege = strdup(result.front().c_str());
if (privilege == nullptr) {
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
- if (result.size() != 2)
- return PMINFO_R_ERROR;
- if (result.front().empty() || result.front().size() == 0 ||
- result.back().empty() || result.back().size() == 0)
+ for (auto& result : result_list) {
+ if (result.size() != 2 || result.front().empty() || result.back().empty())
return PMINFO_R_ERROR;
- std::string app_control = result.front();
- std::stringstream ss(app_control);
+ std::stringstream ss(result.front());
std::string token;
while (std::getline(ss, token, '|')) {
if (token.compare(std::string(operation))) {
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
+ for (auto& result : result_list) {
if (result.size() != 1) {
LOG(ERROR) << "Invalid result";
g_list_free_full(*list, free);
if (result_list.size() == 0)
return PMINFO_R_ENOENT;
- for (auto result : result_list) {
+ for (auto& result : result_list) {
if (result.size() != 3) {
LOG(ERROR) << "Invalid result";
g_slist_free_full(*update_info_list, __free_update_info);
result_map.insert(make_pair(std::string(l_pkgid), "-1"));
result_map.insert(make_pair(std::string(r_pkgid), "-1"));
- for (auto &certinfo : certinfo_list)
+ for (auto& certinfo : certinfo_list)
result_map[certinfo.front()] = certinfo.back();
- if (result_map.find(std::string(l_pkgid))->second == "-1" &&
- result_map.find(std::string(r_pkgid))->second == "-1")
+ auto l_iter = result_map.find(l_pkgid);
+ auto r_iter = result_map.find(r_pkgid);
+ if (l_iter->second == "-1" && r_iter->second == "-1")
*result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
- else if (result_map.find(std::string(l_pkgid))->second == "-1")
+ else if (l_iter->second == "-1")
*result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
- else if (result_map.find(std::string(r_pkgid))->second == "-1")
+ else if (r_iter->second == "-1")
*result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
- else if (result_map.find(std::string(l_pkgid))->second ==
- result_map.find(std::string(r_pkgid))->second)
+ else if (l_iter->second == r_iter->second)
*result = PMINFO_CERT_COMPARE_MATCH;
else
*result = PMINFO_CERT_COMPARE_MISMATCH;
auto pkgid_list = return_parcel->GetResult();
std::map<std::string, std::string> result_map;
- for (auto &pkgid : pkgid_list)
+ for (auto& pkgid : pkgid_list)
result_map.insert(make_pair(pkgid.front(), pkgid.back()));
- if (result_map.find(std::string(l_appid)) == result_map.end()) {
+ auto l_iter = result_map.find(l_appid);
+ if (l_iter == result_map.end()) {
LOG(ERROR) << "Cannot find pkgid of app " << l_appid
<< " for uid " << uid;
return PMINFO_R_ENOENT;
- } else if (result_map.find(std::string(r_appid)) == result_map.end()) {
+ }
+ auto r_iter = result_map.find(r_appid);
+ if (r_iter == result_map.end()) {
LOG(ERROR) << "Cannot find pkgid of app " << r_appid
<< " for uid " << uid;
return PMINFO_R_ENOENT;
}
- const char* l_pkgid = result_map.find(std::string(l_appid))->second.c_str();
- const char* r_pkgid = result_map.find(std::string(r_appid))->second.c_str();
+ const char* l_pkgid = l_iter->second.c_str();
+ const char* r_pkgid = r_iter->second.c_str();
return _certinfo_compare_pkg_certinfo(l_pkgid, r_pkgid, result);
}
return PMINFO_R_ERROR;
auto ptr = client.GetResultParcel();
- if (ptr == nullptr) {
+ if (ptr == nullptr) {
LOG(ERROR) << "Fail to get return parcelable";
return PMINFO_R_ERROR;
}
- if (ptr->GetRequestResult() != PMINFO_R_OK) {
+ if (ptr->GetRequestResult() != PMINFO_R_OK) {
LOG(ERROR) << "Request fail";
return PMINFO_R_ERROR;
}
- if (ptr->GetType() != pcp::ParcelableType::Result) {
+ if (ptr->GetType() != pcp::ParcelableType::Result) {
LOG(ERROR) << "Invalid parcelable type";
return PMINFO_R_ERROR;
}