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()) {
124 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
125 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
126 client.GetResultParcel()));
127 tizen_base::Parcel parcel;
128 parcel.ReadParcelable(return_parcel.get());
130 // result_list is vector of string vector
131 char *label = nullptr;
132 auto result_list = return_parcel->GetResult();
133 for (auto result : result_list) {
134 // result is string vector
135 // it only has one string or not.
136 if (result.front().empty() || result.front().length() == 0)
138 label = strdup(result.front().c_str());
139 if (label == nullptr) {
140 LOG(ERROR) << "Out of memory";
148 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
149 const char *providerid, const char *type, uid_t uid,
150 char **appid, char **access) {
151 char *query = nullptr;
152 query = sqlite3_mprintf("SELECT app_id, access FROM "
153 "package_app_data_control WHERE "
154 "providerid=%Q AND type=%Q", providerid, type);
155 if (query == nullptr) {
156 LOG(ERROR) << "Out of memory";
157 return PMINFO_R_ERROR;
160 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
161 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
163 pkgmgr_client::PkgInfoClient client(parcelable, uid,
164 pkgmgr_common::ReqType::QUERY);
165 if (!client.SendRequest()) {
167 return PMINFO_R_ERROR;
170 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
171 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
172 client.GetResultParcel()));
173 tizen_base::Parcel parcel;
174 parcel.ReadParcelable(return_parcel.get());
176 // result_list is vector of string vector
177 auto result_list = return_parcel->GetResult();
178 if (result_list.size() == 0)
179 return PMINFO_R_ENOENT;
180 for (auto result : result_list) {
181 if (result.size() != 2)
182 return PMINFO_R_ERROR;
183 if (result.front().empty() || result.front().size() == 0 ||
184 result.back().empty() || result.back().size() == 0)
185 return PMINFO_R_ERROR;
186 *appid = strdup(result.front().c_str());
187 *access = strdup(result.back().c_str());
188 if (*appid == nullptr || *access == nullptr) {
189 LOG(ERROR) << "Out of memory";
190 return PMINFO_R_ERROR;
197 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
198 const char *providerid, uid_t uid, char **appid) {
199 char *query = nullptr;
201 query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
202 "WHERE providerid=%Q", providerid);
204 LOGE("Out of memory");
205 return PMINFO_R_ERROR;
207 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
208 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
210 pkgmgr_client::PkgInfoClient client(parcelable, uid,
211 pkgmgr_common::ReqType::QUERY);
212 if (!client.SendRequest()) {
214 return PMINFO_R_ERROR;
216 // TODO: deliver rawdata to reqhandler directly if server is not working
218 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
219 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
220 client.GetResultParcel()));
221 tizen_base::Parcel parcel;
222 parcel.ReadParcelable(return_parcel.get());
225 // result_list is vector of string vector
226 auto result_list = return_parcel->GetResult();
227 if (result_list.size() == 0)
228 return PMINFO_R_ENOENT;
229 for (auto result : result_list) {
230 if (result.size() != 1)
231 return PMINFO_R_ERROR;
232 if (result.front().empty() || result.front().size() == 0)
233 return PMINFO_R_ERROR;
234 *appid = strdup(result.front().c_str());
235 if (*appid == nullptr) {
236 LOG(ERROR) << "Out of memory";
237 return PMINFO_R_ERROR;
244 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
245 const char *providerid, const char *type, uid_t uid,
246 char **appid, char **trusted) {
247 char *query = nullptr;
248 query = sqlite3_mprintf(
249 "SELECT app_id, trusted FROM package_app_data_control "
250 "WHERE providerid=%Q AND type=%Q", providerid, type);
252 LOGE("Out of memory");
253 return PMINFO_R_ERROR;
256 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
257 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
259 pkgmgr_client::PkgInfoClient client(parcelable, uid,
260 pkgmgr_common::ReqType::QUERY);
261 if (!client.SendRequest()) {
263 return PMINFO_R_ERROR;
265 // TODO: deliver rawdata to reqhandler directly if server is not working
267 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
268 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
269 client.GetResultParcel()));
270 tizen_base::Parcel parcel;
271 parcel.ReadParcelable(return_parcel.get());
273 // result_list is vector of string vector
274 auto result_list = return_parcel->GetResult();
275 if (result_list.size() == 0)
276 return PMINFO_R_ENOENT;
277 for (auto result : result_list) {
278 if (result.size() != 2)
279 return PMINFO_R_ERROR;
280 if (result.front().empty() || result.front().size() == 0 ||
281 result.back().empty() || result.back().size() == 0)
282 return PMINFO_R_ERROR;
283 *appid = strdup(result.front().c_str());
284 *trusted = strdup(result.back().c_str());
285 if (*appid == nullptr || *trusted == nullptr) {
286 LOG(ERROR) << "Out of memory";
287 return PMINFO_R_ERROR;
294 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
295 const char *providerid, const char *type, uid_t uid,
296 GList **privileges) {
297 char *query = nullptr;
298 query = sqlite3_mprintf(
299 "SELECT privilege FROM package_app_data_control_privilege "
300 "WHERE providerid=%Q AND type=%Q", providerid, type);
302 LOGE("Out of memory");
303 return PMINFO_R_ERROR;
306 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
307 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
309 pkgmgr_client::PkgInfoClient client(parcelable, uid,
310 pkgmgr_common::ReqType::QUERY);
311 if (!client.SendRequest()) {
313 return PMINFO_R_ERROR;
315 // TODO: deliver rawdata to reqhandler directly if server is not working
317 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
318 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
319 client.GetResultParcel()));
320 tizen_base::Parcel parcel;
321 parcel.ReadParcelable(return_parcel.get());
323 // result_list is vector of string vector
324 auto result_list = return_parcel->GetResult();
325 if (result_list.size() == 0)
326 return PMINFO_R_ENOENT;
328 for (auto result : result_list) {
329 if (result.size() != 1)
330 return PMINFO_R_ERROR;
331 if (result.front().empty() || result.front().size() == 0)
332 return PMINFO_R_ERROR;
333 char *privilege = strdup(result.front().c_str());
334 if (privilege == nullptr) {
335 LOG(ERROR) << "Out of memory";
336 return PMINFO_R_ERROR;
338 *privileges = g_list_append(*privileges, privilege);
344 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
345 const char *appid, const char *operation, uid_t uid, GList **privileges) {
346 char *query = nullptr;
347 query = sqlite3_mprintf(
348 "SELECT app_control, privilege FROM package_app_app_control_privilege "
349 "WHERE app_id=%Q", appid);
351 LOG(ERROR) << "Out of memory";
352 return PMINFO_R_ERROR;
355 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
356 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
358 pkgmgr_client::PkgInfoClient client(parcelable, uid,
359 pkgmgr_common::ReqType::QUERY);
360 if (!client.SendRequest()) {
362 return PMINFO_R_ERROR;
364 // TODO: deliver rawdata to reqhandler directly if server is not working
366 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
367 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
368 client.GetResultParcel()));
369 tizen_base::Parcel parcel;
370 parcel.ReadParcelable(return_parcel.get());
372 // result_list is vector of string vector
373 auto result_list = return_parcel->GetResult();
374 if (result_list.size() == 0)
375 return PMINFO_R_ENOENT;
377 for (auto result : result_list) {
378 if (result.size() != 2)
379 return PMINFO_R_ERROR;
380 if (result.front().empty() || result.front().size() == 0 ||
381 result.back().empty() || result.back().size() == 0)
382 return PMINFO_R_ERROR;
383 std::string app_control = result.front();
384 std::stringstream ss(app_control);
386 while (std::getline(ss, token, '|')) {
387 if (token.compare(std::string(operation))) {
388 char *privilege = strdup(result.back().c_str());
389 if (privilege == nullptr) {
390 LOG(ERROR) << "Out of memory";
391 return PMINFO_R_ERROR;
393 *privileges = g_list_append(*privileges, privilege);