Merge remote-tracking branch 'origin/master' into fix_log
[platform/core/appfw/pkgmgr-info.git] / src / client / pkginfo_client.cc
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.
4
5 #include "pkginfo_client.hh"
6
7 #include "parcelable_factory.hh"
8 #include "get_appinfo_request_handler.hh"
9 #include "get_cert_request_handler.hh"
10 #include "get_depinfo_request_handler.hh"
11 #include "get_pkginfo_request_handler.hh"
12 #include "query_request_handler.hh"
13 #include "set_cert_request_handler.hh"
14 #include "set_pkginfo_request_handler.hh"
15
16 #include <parcel.hh>
17
18 #include <vconf.h>
19
20 #include "pkgmgrinfo_debug.h"
21
22 #include <string>
23
24 namespace pkgmgr_client {
25
26 static const char SOCK_PATH[] = "/run/pkgmgr-info-server";
27
28 PkgInfoClient::PkgInfoClient(
29     std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
30     uid_t uid, pkgmgr_common::ReqType req_type)
31     : parcel_(parcel),
32       result_parcel_(nullptr),
33       uid_(uid),
34       req_type_(req_type),
35       is_offline_(false) {
36   socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
37 }
38
39 PkgInfoClient::~PkgInfoClient() {
40   if (socket_ != nullptr)
41     socket_->Disconnect();
42 }
43
44 bool PkgInfoClient::SendRequest() {
45   if (socket_ == nullptr) {
46     LOGE("Socket is not ready");
47     return false;
48   }
49   if (!socket_->Connect()) {
50     LOGE("Failed to connect client socket, try to direct access");
51     socket_->Disconnect();
52     is_offline_ = true;
53     return RequestHandlerDirectAccess();
54   }
55
56   if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
57     LOGE("fail to send data");
58     socket_->Disconnect();
59     return false;
60   }
61
62   tizen_base::Parcel p;
63   p.WriteParcelable(*parcel_.get());
64   const auto& raw = p.GetRaw();
65   int len = raw.size();
66
67   if (socket_->SendData(&len, sizeof(len)) != 0) {
68     LOGE("fail to send data");
69     socket_->Disconnect();
70     return false;
71   }
72
73   if (socket_->SendData(&raw[0], len) != 0) {
74     LOGE("Fail to send data");
75     socket_->Disconnect();
76     return false;
77   }
78
79   return true;
80 }
81
82 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
83 PkgInfoClient::GetResultParcel() {
84   if (is_offline_) return result_parcel_;
85
86   if (socket_ == nullptr) {
87     LOGE("Socket is not ready");
88     return nullptr;
89   }
90   int len = 0;
91   if (socket_->ReceiveData(&len, sizeof(len)) != 0) {
92     LOGE("Fail to receive data");
93     socket_->Disconnect();
94     return nullptr;
95   }
96
97   unsigned char* raw = new (std::nothrow) unsigned char[len];
98   if (raw == nullptr) {
99     LOGE("Out of memory");
100     socket_->Disconnect();
101     return nullptr;
102   }
103
104   if (socket_->ReceiveData(raw, len) != 0) {
105     LOGE("Fail to receive data");
106     socket_->Disconnect();
107     delete[] raw;
108     return nullptr;
109   }
110   socket_->Disconnect();
111
112   auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
113       raw, len);
114   delete[] raw;
115
116   return res;
117 }
118
119 bool PkgInfoClient::RequestHandlerDirectAccess() {
120   std::unique_ptr<pkgmgr_server::request_handler::AbstractRequestHandler>
121       handler;
122   switch (req_type_) {
123     case pkgmgr_common::ReqType::GET_PKG_INFO:
124       handler.reset(
125           new pkgmgr_server::request_handler::GetPkginfoRequestHandler());
126       break;
127     case pkgmgr_common::ReqType::GET_APP_INFO:
128       handler.reset(
129           new pkgmgr_server::request_handler::GetAppinfoRequestHandler());
130       break;
131     case pkgmgr_common::ReqType::SET_PKG_INFO:
132       handler.reset(
133           new pkgmgr_server::request_handler::SetPkginfoRequestHandler());
134       break;
135     case pkgmgr_common::ReqType::SET_CERT_INFO:
136       handler.reset(
137           new pkgmgr_server::request_handler::SetCertRequestHandler());
138       break;
139     case pkgmgr_common::ReqType::GET_CERT_INFO:
140       handler.reset(
141           new pkgmgr_server::request_handler::GetCertRequestHandler());
142       break;
143     case pkgmgr_common::ReqType::GET_PKG_DEP_INFO:
144       handler.reset(
145           new pkgmgr_server::request_handler::GetDepinfoRequestHandler());
146       break;
147     case pkgmgr_common::ReqType::QUERY:
148       handler.reset(new pkgmgr_server::request_handler::QueryRequestHandler());
149       break;
150     default:
151       handler.reset(nullptr);
152       break;
153   }
154
155   if (handler == nullptr) {
156     LOGE("Can't reset handler with type[%d]", req_type_);
157     return false;
158   }
159
160   tizen_base::Parcel p;
161   p.WriteParcelable(*parcel_.get());
162   std::vector<uint8_t> raw = p.GetRaw();
163
164   handler->HandleRequest(&raw[0], raw.size(), vconf_get_str(VCONFKEY_LANGSET));
165   auto result = handler->GetResult();
166   if (result.size() == 0) return true;
167
168   result_parcel_.reset(pkgmgr_common::parcel::ParcelableFactory::GetInst()
169                            .CreateParcel(&result[0], result.size())
170                            .release());
171
172   return true;
173 }
174
175 }  // namespace pkgmgr_client