2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "manager/pkginfo_manager.h"
19 #include <sys/types.h>
26 #include "pkgmgrinfo_private.h"
29 #include "common/parcel/appinfo_parcelable.hh"
30 #include "common/parcel/filter_parcelable.hh"
31 #include "common/parcel/pkginfo_parcelable.hh"
32 #include "common/parcel/query_parcelable.hh"
33 #include "common/parcel/result_parcelable.hh"
35 #include "client/pkginfo_client.hh"
42 #define LOG_TAG "PKGMGR_INFO"
47 #define EXPORT_API __attribute__((visibility("default")))
49 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
50 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
51 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
52 new pkgmgr_common::parcel::FilterParcelable(uid,
53 static_cast<pkgmgrinfo_filter_x*>(filter), flag));
55 pkgmgr_client::PkgInfoClient client(parcelable, uid,
56 pkgmgr_common::ReqType::GET_PKG_INFO);
57 if (!client.SendRequest())
58 return PMINFO_R_ERROR;
60 std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
61 std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
62 client.GetResultParcel()));
64 tizen_base::Parcel parcel;
65 parcel.ReadParcelable(return_parcel.get());
67 auto result_list = return_parcel->GetPkgInfo();
68 // TODO: check noentry error has returned if size of result_list is 0
69 for (auto& pkginfo : result_list)
70 g_hash_table_insert(packages, (gpointer)pkginfo->package,
76 // TODO: Need to add target db uid to identify which database to be searched
77 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
78 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
79 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
80 new pkgmgr_common::parcel::FilterParcelable(uid,
81 static_cast<pkgmgrinfo_filter_x*>(filter), flag));
83 pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
84 if (!client.SendRequest())
85 return PMINFO_R_ERROR;
87 std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
88 std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
89 client.GetResultParcel()));
91 tizen_base::Parcel parcel;
92 parcel.ReadParcelable(return_parcel.get());
93 auto result_list = return_parcel->GetAppInfo();
94 for (auto& appinfo : result_list)
95 g_hash_table_insert(packages, (gpointer)appinfo->appid,
101 extern "C" EXPORT_API char *_appinfo_get_localed_label(
102 const char *appid, const char *locale, uid_t uid) {
103 char *query = nullptr;
104 query = sqlite3_mprintf(
105 "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
106 "WHERE app_id=%Q AND app_locale=%Q),"
107 "(SELECT app_label FROM package_app_localized_info WHERE "
108 "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
109 if (query == nullptr) {
110 LOG(ERROR) << "Out of memory";
114 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
115 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
117 pkgmgr_client::PkgInfoClient client(parcelable, uid,
118 pkgmgr_common::ReqType::QUERY);
119 if (!client.SendRequest())
122 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
123 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
124 client.GetResultParcel()));
125 tizen_base::Parcel parcel;
126 parcel.ReadParcelable(return_parcel.get());
128 // result_list is vector of string vector
130 auto result_list = return_parcel->GetResult();
131 for (auto result : result_list) {
132 // result is string vector
133 // it only has one string or not.
134 if (result.front().empty() || result.front().length() == 0)
136 label = strdup(result.front().c_str());
137 if (label == nullptr) {
138 LOG(ERROR) << "Out of memory";
146 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
147 const char *providerid, const char *type, uid_t uid,
148 char **appid, char **access) {
149 char *query = nullptr;
150 query = sqlite3_mprintf("SELECT app_id, access FROM "
151 "package_app_data_control WHERE "
152 "providerid=%Q AND type=%Q", providerid, type);
153 if (query == nullptr) {
154 LOG(ERROR) << "Out of memory";
155 return PMINFO_R_ERROR;
158 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
159 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
161 pkgmgr_client::PkgInfoClient client(parcelable, uid,
162 pkgmgr_common::ReqType::QUERY);
163 if (!client.SendRequest()) {
165 return PMINFO_R_ERROR;
168 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
169 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
170 client.GetResultParcel()));
171 tizen_base::Parcel parcel;
172 parcel.ReadParcelable(return_parcel.get());
174 // result_list is vector of string vector
175 auto result_list = return_parcel->GetResult();
176 if (result_list.size() == 0)
177 return PMINFO_R_ENOENT;
178 for (auto result : result_list) {
179 if (result.size() != 2)
180 return PMINFO_R_ERROR;
181 if (result.front().empty() || result.front().size() == 0 ||
182 result.back().empty() || result.back().size() == 0)
183 return PMINFO_R_ERROR;
184 *appid = strdup(result.front().c_str());
185 *access = strdup(result.back().c_str());
186 if (*appid == nullptr || *access == nullptr) {
187 LOG(ERROR) << "Out of memory";
188 return PMINFO_R_ERROR;
195 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
196 const char *providerid, uid_t uid, char **appid) {
197 char *query = nullptr;
199 query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
200 "WHERE providerid=%Q", providerid);
202 LOGE("Out of memory");
203 return PMINFO_R_ERROR;
205 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
206 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
208 pkgmgr_client::PkgInfoClient client(parcelable, uid,
209 pkgmgr_common::ReqType::QUERY);
210 if (!client.SendRequest()) {
212 return PMINFO_R_ERROR;
214 // TODO: deliver rawdata to reqhandler directly if server is not working
216 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
217 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
218 client.GetResultParcel()));
219 tizen_base::Parcel parcel;
220 parcel.ReadParcelable(return_parcel.get());
223 // result_list is vector of string vector
224 auto result_list = return_parcel->GetResult();
225 if (result_list.size() == 0)
226 return PMINFO_R_ENOENT;
227 for (auto result : result_list) {
228 if (result.size() != 1)
229 return PMINFO_R_ERROR;
230 if (result.front().empty() || result.front().size() == 0)
231 return PMINFO_R_ERROR;
232 *appid = strdup(result.front().c_str());
233 if (*appid == nullptr) {
234 LOG(ERROR) << "Out of memory";
235 return PMINFO_R_ERROR;
242 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
243 const char *providerid, const char *type, uid_t uid,
244 char **appid, char **trusted) {
245 char *query = nullptr;
246 query = sqlite3_mprintf(
247 "SELECT app_id, trusted FROM package_app_data_control "
248 "WHERE providerid=%Q AND type=%Q", providerid, type);
250 LOGE("Out of memory");
251 return PMINFO_R_ERROR;
254 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
255 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
257 pkgmgr_client::PkgInfoClient client(parcelable, uid,
258 pkgmgr_common::ReqType::QUERY);
259 if (!client.SendRequest()) {
261 return PMINFO_R_ERROR;
263 // TODO: deliver rawdata to reqhandler directly if server is not working
265 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
266 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
267 client.GetResultParcel()));
268 tizen_base::Parcel parcel;
269 parcel.ReadParcelable(return_parcel.get());
271 // result_list is vector of string vector
272 auto result_list = return_parcel->GetResult();
273 if (result_list.size() == 0)
274 return PMINFO_R_ENOENT;
275 for (auto result : result_list) {
276 if (result.size() != 2)
277 return PMINFO_R_ERROR;
278 if (result.front().empty() || result.front().size() == 0 ||
279 result.back().empty() || result.back().size() == 0)
280 return PMINFO_R_ERROR;
281 *appid = strdup(result.front().c_str());
282 *trusted = strdup(result.back().c_str());
283 if (*appid == nullptr || *trusted == nullptr) {
284 LOG(ERROR) << "Out of memory";
285 return PMINFO_R_ERROR;
292 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
293 const char *providerid, const char *type, uid_t uid,
294 GList **privileges) {
295 char *query = nullptr;
296 query = sqlite3_mprintf(
297 "SELECT privilege FROM package_app_data_control_privilege "
298 "WHERE providerid=%Q AND type=%Q", providerid, type);
300 LOGE("Out of memory");
301 return PMINFO_R_ERROR;
304 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
305 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
307 pkgmgr_client::PkgInfoClient client(parcelable, uid,
308 pkgmgr_common::ReqType::QUERY);
309 if (!client.SendRequest()) {
311 return PMINFO_R_ERROR;
313 // TODO: deliver rawdata to reqhandler directly if server is not working
315 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
316 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
317 client.GetResultParcel()));
318 tizen_base::Parcel parcel;
319 parcel.ReadParcelable(return_parcel.get());
321 // result_list is vector of string vector
322 auto result_list = return_parcel->GetResult();
323 if (result_list.size() == 0)
324 return PMINFO_R_ENOENT;
326 for (auto result : result_list) {
327 if (result.size() != 1)
328 return PMINFO_R_ERROR;
329 if (result.front().empty() || result.front().size() == 0)
330 return PMINFO_R_ERROR;
331 char *privilege = strdup(result.front().c_str());
332 if (privilege == nullptr) {
333 LOG(ERROR) << "Out of memory";
334 return PMINFO_R_ERROR;
336 *privileges = g_list_append(*privileges, privilege);
342 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
343 const char *appid, const char *operation, uid_t uid, GList **privileges) {
344 char *query = nullptr;
345 query = sqlite3_mprintf(
346 "SELECT app_control, privilege FROM package_app_app_control_privilege "
347 "WHERE app_id=%Q", appid);
349 LOG(ERROR) << "Out of memory";
350 return PMINFO_R_ERROR;
353 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
354 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
356 pkgmgr_client::PkgInfoClient client(parcelable, uid,
357 pkgmgr_common::ReqType::QUERY);
358 if (!client.SendRequest()) {
360 return PMINFO_R_ERROR;
362 // TODO: deliver rawdata to reqhandler directly if server is not working
364 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
365 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
366 client.GetResultParcel()));
367 tizen_base::Parcel parcel;
368 parcel.ReadParcelable(return_parcel.get());
370 // result_list is vector of string vector
371 auto result_list = return_parcel->GetResult();
372 if (result_list.size() == 0)
373 return PMINFO_R_ENOENT;
375 for (auto result : result_list) {
376 if (result.size() != 2)
377 return PMINFO_R_ERROR;
378 if (result.front().empty() || result.front().size() == 0 ||
379 result.back().empty() || result.back().size() == 0)
380 return PMINFO_R_ERROR;
381 std::string app_control = result.front();
382 std::stringstream ss(app_control);
384 while (std::getline(ss, token, '|')) {
385 if (token.compare(std::string(operation))) {
386 char *privilege = strdup(result.back().c_str());
387 if (privilege == nullptr) {
388 LOG(ERROR) << "Out of memory";
389 return PMINFO_R_ERROR;
391 *privileges = g_list_append(*privileges, privilege);