1 // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "pkginfo_client.hh"
7 #include <cpu-boosting.h>
15 #include "parcelable_factory.hh"
16 #include "system_locale.hh"
17 #include "ready_checker.hh"
18 #include "utils/logging.hh"
20 #include "pkgmgrinfo_debug.h"
21 #include "pkgmgrinfo_private.h"
23 #define LIBPKGMGR_INFO LIB_PATH "/libpkgmgr-info-server.so.0"
24 #define DIRECT_ACCESS_FUNC "_request_handler_direct_access"
26 namespace pkgmgr_client {
28 constexpr const char SOCK_PATH[] = "/run/pkgmgr-info-server";
29 constexpr const char SERVER_READY[] = "/run/.pkginfo_server_ready";
30 constexpr const char DEST_PROCESS_NAME[] = "pkgmgr-info";
32 PkgInfoClient::CPUInheritanceInvoker::CPUInheritanceInvoker()
33 : set_complete_(false) {}
35 PkgInfoClient::CPUInheritanceInvoker::~CPUInheritanceInvoker() {
36 ClearCPUInheritance();
39 void PkgInfoClient::CPUInheritanceInvoker::SetCPUInheritance() {
40 int ret = resource_set_cpu_inheritance(gettid(), DEST_PROCESS_NAME, -1);
42 LOG(ERROR) << "set cpu inheritance fail ret : " << ret;
49 void PkgInfoClient::CPUInheritanceInvoker::ClearCPUInheritance() {
53 int ret = resource_clear_cpu_inheritance(gettid(), DEST_PROCESS_NAME);
55 LOG(ERROR) << "clear cpu inheritance fail ret : " << ret;
59 set_complete_ = false;
62 PkgInfoClient::PkgInfoClient(
63 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
64 uid_t uid, pkgmgr_common::ReqType req_type)
66 result_parcel_(nullptr),
70 socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
73 bool PkgInfoClient::SendRequest() {
74 static pkgmgr_common::ReadyChecker check_server(SERVER_READY);
75 if (socket_ == nullptr) {
76 LOG(ERROR) << "Socket is not ready";
81 p.WriteParcelable(*parcel_.get());
82 const auto& raw = p.GetRaw();
85 // CREATE_DB request type need to be executed directly by the caller
86 if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) {
88 return RequestHandlerDirectAccess(p.GetRaw());
91 if (!check_server.IsReady()) {
92 LOG(WARNING) << "Server is not ready, try to direct access";
94 return RequestHandlerDirectAccess(p.GetRaw());
97 LOG(WARNING) << "Try to send request, Request type: "
98 << pkgmgr_common::ReqTypeToString(req_type_);
100 cpu_inheritance_invoker_.SetCPUInheritance();
101 if (!socket_->Connect(req_type_)) {
102 LOG(ERROR) << "Failed to connect client socket, try to direct access";
104 return RequestHandlerDirectAccess(p.GetRaw());
107 if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
108 LOG(ERROR) << "fail to send data";
112 if (socket_->SendData(&len, sizeof(len)) != 0) {
113 LOG(ERROR) << "fail to send data";
117 if (socket_->SendData(&raw[0], len) != 0) {
118 LOG(ERROR) << "Fail to send data";
125 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
126 PkgInfoClient::GetResultParcel() {
128 return result_parcel_;
130 if (socket_ == nullptr) {
131 LOG(ERROR) << "Socket is not ready";
136 if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
137 LOG(ERROR) << "Fail to receive data";
141 unsigned char* raw = new (std::nothrow) unsigned char[len];
142 if (raw == nullptr) {
143 LOG(ERROR) << "Out of memory";
147 if (socket_->ReceiveData(raw, len) != 0) {
148 LOG(ERROR) << "Fail to receive data";
153 cpu_inheritance_invoker_.ClearCPUInheritance();
155 auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
162 bool PkgInfoClient::RequestHandlerDirectAccess(
163 const std::vector<uint8_t>& raw) {
164 static void* handle = nullptr;
165 static void* (*dl_func)(int, const unsigned char*, int, const char *);
167 if (handle == nullptr) {
168 handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY);
170 LOG(ERROR) << "Failed to open library: " << LIBPKGMGR_INFO
171 << ", : " << dlerror();
174 dl_func = reinterpret_cast<void* (*)(
175 int, const unsigned char*, int, const char *)>(
176 dlsym(handle, DIRECT_ACCESS_FUNC));
177 if (dl_func == nullptr) {
178 LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in "
186 result_parcel_.reset(
187 reinterpret_cast<pkgmgr_common::parcel::AbstractParcelable *>(
188 dl_func(req_type_, &raw[0], raw.size(),
189 pkgmgr_common::SystemLocale::GetInst(false).Get().c_str())));
194 } // namespace pkgmgr_client