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"
14 #include "parcelable_factory.hh"
16 #include "pkgmgrinfo_debug.h"
17 #include "pkgmgrinfo_private.h"
19 #define LIBPKGMGR_INFO "/usr/lib/libpkgmgr-info-server.so.0"
20 #define DIRECT_ACCESS_FUNC "_request_handler_direct_access"
22 namespace pkgmgr_client {
24 constexpr const char SOCK_PATH[] = "/run/pkgmgr-info-server";
26 PkgInfoClient::PkgInfoClient(
27 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
28 uid_t uid, pkgmgr_common::ReqType req_type)
30 result_parcel_(nullptr),
34 socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
37 PkgInfoClient::~PkgInfoClient() {
38 if (socket_ != nullptr)
39 socket_->Disconnect();
42 bool PkgInfoClient::SendRequest() {
43 if (socket_ == nullptr) {
44 LOGE("Socket is not ready");
48 // CREATE_DB request type need to be executed directly by the caller
49 if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) {
51 return RequestHandlerDirectAccess();
54 if (!socket_->Connect()) {
55 LOGE("Failed to connect client socket, try to direct access");
56 socket_->Disconnect();
58 return RequestHandlerDirectAccess();
61 if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
62 LOGE("fail to send data");
63 socket_->Disconnect();
68 p.WriteParcelable(*parcel_.get());
69 const auto& raw = p.GetRaw();
72 if (socket_->SendData(&len, sizeof(len)) != 0) {
73 LOGE("fail to send data");
74 socket_->Disconnect();
78 if (socket_->SendData(&raw[0], len) != 0) {
79 LOGE("Fail to send data");
80 socket_->Disconnect();
87 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
88 PkgInfoClient::GetResultParcel() {
90 return result_parcel_;
92 if (socket_ == nullptr) {
93 LOGE("Socket is not ready");
97 if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
98 LOGE("Fail to receive data");
99 socket_->Disconnect();
103 unsigned char* raw = new (std::nothrow) unsigned char[len];
104 if (raw == nullptr) {
105 LOGE("Out of memory");
106 socket_->Disconnect();
110 if (socket_->ReceiveData(raw, len) != 0) {
111 LOGE("Fail to receive data");
112 socket_->Disconnect();
116 socket_->Disconnect();
118 auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
125 bool PkgInfoClient::RequestHandlerDirectAccess() {
126 tizen_base::Parcel p;
127 p.WriteParcelable(*parcel_.get());
128 std::vector<uint8_t> raw = p.GetRaw();
129 std::unique_ptr<char, decltype(std::free)*> locale(
130 _get_system_locale(), std::free);
131 if (locale.get() == nullptr)
134 static void* handle = nullptr;
135 static void* (*dl_func)(int, unsigned char*, int, const char *);
137 if (handle == nullptr) {
138 handle = dlopen(LIBPKGMGR_INFO, RTLD_LOCAL | RTLD_LAZY);
140 LOGE("Failed to open library: %s (%s)", LIBPKGMGR_INFO, dlerror());
143 dl_func = reinterpret_cast<void* (*)(int, unsigned char*, int, const char *)>(
144 dlsym(handle, DIRECT_ACCESS_FUNC));
145 if (dl_func == nullptr) {
146 LOGE("cannot find %s symbol in (%s)", DIRECT_ACCESS_FUNC, LIBPKGMGR_INFO);
153 result_parcel_.reset(
154 reinterpret_cast<pkgmgr_common::parcel::AbstractParcelable *>(
155 dl_func(req_type_, &raw[0], raw.size(), locale.get())));
160 } // namespace pkgmgr_client