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>
16 #include "parcelable_factory.hh"
17 #include "system_locale.hh"
18 #include "ready_checker.hh"
19 #include "utils/logging.hh"
21 #include "pkgmgrinfo_debug.h"
22 #include "pkgmgrinfo_private.h"
24 #define LIBPKGMGR_INFO LIB_PATH "/libpkgmgr-info-server.so.0"
25 #define DIRECT_ACCESS_FUNC "_request_handler_direct_access"
27 namespace pkgmgr_client {
29 constexpr const char SOCK_PATH[] = "/run/pkgmgr-info-server";
30 constexpr const char SERVER_READY[] = "/run/.pkginfo_server_ready";
31 constexpr const char DEST_PROCESS_NAME[] = "pkgmgr-info";
33 PkgInfoClient::CPUInheritanceInvoker::CPUInheritanceInvoker()
34 : set_complete_(false) {}
36 PkgInfoClient::CPUInheritanceInvoker::~CPUInheritanceInvoker() {
37 ClearCPUInheritance();
40 void PkgInfoClient::CPUInheritanceInvoker::SetCPUInheritance() {
41 int ret = resource_set_cpu_inheritance(gettid(), DEST_PROCESS_NAME, -1);
43 LOG(ERROR) << "set cpu inheritance fail ret : " << ret;
50 void PkgInfoClient::CPUInheritanceInvoker::ClearCPUInheritance() {
54 int ret = resource_clear_cpu_inheritance(gettid(), DEST_PROCESS_NAME);
56 LOG(ERROR) << "clear cpu inheritance fail ret : " << ret;
60 set_complete_ = false;
63 PkgInfoClient::PkgInfoClient(
64 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
65 uid_t uid, pkgmgr_common::ReqType req_type)
67 result_parcel_(nullptr),
71 socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
74 bool PkgInfoClient::SendRequest() {
75 static pkgmgr_common::ReadyChecker check_server(SERVER_READY);
76 if (socket_ == nullptr) {
77 LOG(ERROR) << "Socket is not ready";
82 p.WriteParcelable(*parcel_.get());
83 const auto& raw = p.GetRaw();
86 // CREATE_DB request type need to be executed directly by the caller
87 if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) {
89 return RequestHandlerDirectAccess(p.GetRaw());
92 if (!check_server.IsReady()) {
93 LOG(WARNING) << "Server is not ready, try to direct access";
95 return RequestHandlerDirectAccess(p.GetRaw());
98 LOG(WARNING) << "Try to send request, Request type: "
99 << pkgmgr_common::ReqTypeToString(req_type_);
101 cpu_inheritance_invoker_.SetCPUInheritance();
102 if (!socket_->Connect(req_type_)) {
103 LOG(ERROR) << "Failed to connect client socket, try to direct access";
105 return RequestHandlerDirectAccess(p.GetRaw());
108 if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
109 LOG(ERROR) << "fail to send data";
113 if (socket_->SendData(&len, sizeof(len)) != 0) {
114 LOG(ERROR) << "fail to send data";
118 if (socket_->SendData(&raw[0], len) != 0) {
119 LOG(ERROR) << "Fail to send data";
126 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
127 PkgInfoClient::GetResultParcel() {
129 return result_parcel_;
131 if (socket_ == nullptr) {
132 LOG(ERROR) << "Socket is not ready";
137 if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
138 LOG(ERROR) << "Fail to receive data";
142 unsigned char* raw = new (std::nothrow) unsigned char[len];
143 if (raw == nullptr) {
144 LOG(ERROR) << "Out of memory";
148 if (socket_->ReceiveData(raw, len) != 0) {
149 LOG(ERROR) << "Fail to receive data";
154 LOG(WARNING) << "Success to receive result from server"
156 cpu_inheritance_invoker_.ClearCPUInheritance();
158 auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
165 bool PkgInfoClient::RequestHandlerDirectAccess(
166 const std::vector<uint8_t>& raw) {
167 static std::mutex lock;
168 static void* handle = nullptr;
169 static void* (*dl_func)(int, const unsigned char*, int, const char*);
171 std::unique_lock<std::mutex> u(lock);
172 if (handle == nullptr) {
173 handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY);
175 LOG(ERROR) << "Failed to open library: " << LIBPKGMGR_INFO
176 << ", : " << dlerror();
179 dl_func = reinterpret_cast<void* (*)(
180 int, const unsigned char*, int, const char*)>(
181 dlsym(handle, DIRECT_ACCESS_FUNC));
182 if (dl_func == nullptr) {
183 LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in "
192 result_parcel_.reset(
193 reinterpret_cast<pkgmgr_common::parcel::AbstractParcelable*>(
194 dl_func(req_type_, &raw[0], raw.size(),
195 pkgmgr_common::SystemLocale::GetInst(false).Get().c_str())));
200 } // namespace pkgmgr_client