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