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";
149 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
150 const char *providerid, const char *type, uid_t uid,
151 char **appid, char **access) {
152 char *query = nullptr;
153 query = sqlite3_mprintf("SELECT app_id, access FROM "
154 "package_app_data_control WHERE "
155 "providerid=%Q AND type=%Q", providerid, type);
156 if (query == nullptr) {
157 LOG(ERROR) << "Out of memory";
158 return PMINFO_R_ERROR;
161 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
162 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
164 pkgmgr_client::PkgInfoClient client(parcelable, uid,
165 pkgmgr_common::ReqType::QUERY);
166 if (!client.SendRequest()) {
168 return PMINFO_R_ERROR;
171 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
172 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
173 client.GetResultParcel()));
174 tizen_base::Parcel parcel;
175 parcel.ReadParcelable(return_parcel.get());
177 // result_list is vector of string vector
178 auto result_list = return_parcel->GetResult();
179 if (result_list.size() == 0)
180 return PMINFO_R_ENOENT;
181 for (auto result : result_list) {
182 if (result.size() != 2)
183 return PMINFO_R_ERROR;
184 if (result.front().empty() || result.front().size() == 0 ||
185 result.back().empty() || result.back().size() == 0)
186 return PMINFO_R_ERROR;
187 *appid = strdup(result.front().c_str());
188 *access = strdup(result.back().c_str());
189 if (*appid == nullptr || *access == nullptr) {
190 LOG(ERROR) << "Out of memory";
191 return PMINFO_R_ERROR;
198 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
199 const char *providerid, uid_t uid, char **appid) {
200 char *query = nullptr;
202 query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
203 "WHERE providerid=%Q", providerid);
205 LOGE("Out of memory");
206 return PMINFO_R_ERROR;
208 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
209 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
211 pkgmgr_client::PkgInfoClient client(parcelable, uid,
212 pkgmgr_common::ReqType::QUERY);
213 if (!client.SendRequest()) {
215 return PMINFO_R_ERROR;
217 // TODO: deliver rawdata to reqhandler directly if server is not working
219 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
220 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
221 client.GetResultParcel()));
222 tizen_base::Parcel parcel;
223 parcel.ReadParcelable(return_parcel.get());
226 // result_list is vector of string vector
227 auto result_list = return_parcel->GetResult();
228 if (result_list.size() == 0)
229 return PMINFO_R_ENOENT;
230 for (auto result : result_list) {
231 if (result.size() != 1)
232 return PMINFO_R_ERROR;
233 if (result.front().empty() || result.front().size() == 0)
234 return PMINFO_R_ERROR;
235 *appid = strdup(result.front().c_str());
236 if (*appid == nullptr) {
237 LOG(ERROR) << "Out of memory";
238 return PMINFO_R_ERROR;
245 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
246 const char *providerid, const char *type, uid_t uid,
247 char **appid, char **trusted) {
248 char *query = nullptr;
249 query = sqlite3_mprintf(
250 "SELECT app_id, trusted FROM package_app_data_control "
251 "WHERE providerid=%Q AND type=%Q", providerid, type);
253 LOGE("Out of memory");
254 return PMINFO_R_ERROR;
257 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
258 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
260 pkgmgr_client::PkgInfoClient client(parcelable, uid,
261 pkgmgr_common::ReqType::QUERY);
262 if (!client.SendRequest()) {
264 return PMINFO_R_ERROR;
266 // TODO: deliver rawdata to reqhandler directly if server is not working
268 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
269 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
270 client.GetResultParcel()));
271 tizen_base::Parcel parcel;
272 parcel.ReadParcelable(return_parcel.get());
274 // result_list is vector of string vector
275 auto result_list = return_parcel->GetResult();
276 if (result_list.size() == 0)
277 return PMINFO_R_ENOENT;
278 for (auto result : result_list) {
279 if (result.size() != 2)
280 return PMINFO_R_ERROR;
281 if (result.front().empty() || result.front().size() == 0 ||
282 result.back().empty() || result.back().size() == 0)
283 return PMINFO_R_ERROR;
284 *appid = strdup(result.front().c_str());
285 *trusted = strdup(result.back().c_str());
286 if (*appid == nullptr || *trusted == nullptr) {
287 LOG(ERROR) << "Out of memory";
288 return PMINFO_R_ERROR;
295 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
296 const char *providerid, const char *type, uid_t uid,
297 GList **privileges) {
298 char *query = nullptr;
299 query = sqlite3_mprintf(
300 "SELECT privilege FROM package_app_data_control_privilege "
301 "WHERE providerid=%Q AND type=%Q", providerid, type);
303 LOGE("Out of memory");
304 return PMINFO_R_ERROR;
307 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
308 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
310 pkgmgr_client::PkgInfoClient client(parcelable, uid,
311 pkgmgr_common::ReqType::QUERY);
312 if (!client.SendRequest()) {
314 return PMINFO_R_ERROR;
316 // TODO: deliver rawdata to reqhandler directly if server is not working
318 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
319 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
320 client.GetResultParcel()));
321 tizen_base::Parcel parcel;
322 parcel.ReadParcelable(return_parcel.get());
324 // result_list is vector of string vector
325 auto result_list = return_parcel->GetResult();
326 if (result_list.size() == 0)
327 return PMINFO_R_ENOENT;
329 for (auto result : result_list) {
330 if (result.size() != 1)
331 return PMINFO_R_ERROR;
332 if (result.front().empty() || result.front().size() == 0)
333 return PMINFO_R_ERROR;
334 char *privilege = strdup(result.front().c_str());
335 if (privilege == nullptr) {
336 LOG(ERROR) << "Out of memory";
337 return PMINFO_R_ERROR;
339 *privileges = g_list_append(*privileges, privilege);
345 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
346 const char *appid, const char *operation, uid_t uid, GList **privileges) {
347 char *query = nullptr;
348 query = sqlite3_mprintf(
349 "SELECT app_control, privilege FROM package_app_app_control_privilege "
350 "WHERE app_id=%Q", appid);
352 LOG(ERROR) << "Out of memory";
353 return PMINFO_R_ERROR;
356 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
357 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
359 pkgmgr_client::PkgInfoClient client(parcelable, uid,
360 pkgmgr_common::ReqType::QUERY);
361 if (!client.SendRequest()) {
363 return PMINFO_R_ERROR;
365 // TODO: deliver rawdata to reqhandler directly if server is not working
367 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
368 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
369 client.GetResultParcel()));
370 tizen_base::Parcel parcel;
371 parcel.ReadParcelable(return_parcel.get());
373 // result_list is vector of string vector
374 auto result_list = return_parcel->GetResult();
375 if (result_list.size() == 0)
376 return PMINFO_R_ENOENT;
378 for (auto result : result_list) {
379 if (result.size() != 2)
380 return PMINFO_R_ERROR;
381 if (result.front().empty() || result.front().size() == 0 ||
382 result.back().empty() || result.back().size() == 0)
383 return PMINFO_R_ERROR;
384 std::string app_control = result.front();
385 std::stringstream ss(app_control);
387 while (std::getline(ss, token, '|')) {
388 if (token.compare(std::string(operation))) {
389 char *privilege = strdup(result.back().c_str());
390 if (privilege == nullptr) {
391 LOG(ERROR) << "Out of memory";
392 return PMINFO_R_ERROR;
394 *privileges = g_list_append(*privileges, privilege);
401 extern "C" EXPORT_API int _plugininfo_get_appids(
402 const char *pkgid, const char *plugin_type,
403 const char *plugin_name, GList **list) {
404 if (!pkgid || !plugin_type || !plugin_name || !list) {
405 LOG(ERROR) << "Invalid parameter";
406 return PMINFO_R_EINVAL;
409 char *query = nullptr;
410 query = sqlite3_mprintf(
412 "package_plugin_info WHERE pkgid=%Q AND "
413 "plugin_type=%Q AND plugin_name=%Q",
414 pkgid, plugin_type, plugin_name);
416 LOG(ERROR) << "Out of memory";
417 return PMINFO_R_ERROR;
420 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
421 new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query)));
424 pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
425 pkgmgr_common::ReqType::QUERY);
426 if (!client.SendRequest()) {
427 return PMINFO_R_ERROR;
430 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
431 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
432 client.GetResultParcel()));
433 if (return_parcel->GetCol() != 1) {
434 LOG(ERROR) << "Invalid result";
435 return PMINFO_R_ERROR;
437 // result_list is vector of string vector
438 auto result_list = return_parcel->GetResult();
439 if (result_list.size() == 0)
440 return PMINFO_R_ENOENT;
442 for (auto result : result_list) {
443 if (result.size() != 1) {
444 LOG(ERROR) << "Invalid result";
445 g_list_free_full(*list, free);
446 return PMINFO_R_ERROR;
448 *list = g_list_append(*list, strdup(result[0].c_str()));