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, (gpointer)pkginfo);
71 // TODO: remove element from list. is this work?
78 // TODO: Need to add target db uid to identify which database to be searched
79 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
80 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
81 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
82 new pkgmgr_common::parcel::FilterParcelable(uid,
83 static_cast<pkgmgrinfo_filter_x*>(filter), flag));
85 pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
86 if (!client.SendRequest())
87 return PMINFO_R_ERROR;
89 std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
90 std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
91 client.GetResultParcel()));
93 tizen_base::Parcel parcel;
94 parcel.ReadParcelable(return_parcel.get());
95 auto result_list = return_parcel->GetAppInfo();
96 for (auto& appinfo : result_list) {
97 g_hash_table_insert(packages, (gpointer)appinfo->appid, (gpointer)appinfo);
98 // TODO: remove element from list. is this work?
105 extern "C" EXPORT_API char *_appinfo_get_localed_label(
106 const char *appid, const char *locale, uid_t uid) {
107 char *query = nullptr;
108 query = sqlite3_mprintf(
109 "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
110 "WHERE app_id=%Q AND app_locale=%Q),"
111 "(SELECT app_label FROM package_app_localized_info WHERE "
112 "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
113 if (query == nullptr) {
114 LOG(ERROR) << "Out of memory";
118 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
119 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
121 pkgmgr_client::PkgInfoClient client(parcelable, uid,
122 pkgmgr_common::ReqType::QUERY);
123 if (!client.SendRequest())
126 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
127 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
128 client.GetResultParcel()));
129 tizen_base::Parcel parcel;
130 parcel.ReadParcelable(return_parcel.get());
132 // result_list is vector of string vector
134 auto result_list = return_parcel->GetResult();
135 for (auto result : result_list) {
136 // result is string vector
137 // it only has one string or not.
138 if (result.front().empty() || result.front().length() == 0)
140 label = strdup(result.front().c_str());
141 if (label == nullptr) {
142 LOG(ERROR) << "Out of memory";
150 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
151 const char *providerid, const char *type, uid_t uid,
152 char **appid, char **access) {
153 char *query = nullptr;
154 query = sqlite3_mprintf("SELECT app_id, access FROM "
155 "package_app_data_control WHERE "
156 "providerid=%Q AND type=%Q", providerid, type);
157 if (query == nullptr) {
158 LOG(ERROR) << "Out of memory";
159 return PMINFO_R_ERROR;
162 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
163 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
165 pkgmgr_client::PkgInfoClient client(parcelable, uid,
166 pkgmgr_common::ReqType::QUERY);
167 if (!client.SendRequest())
168 return PMINFO_R_ERROR;
169 // TODO: deliver rawdata to reqhandler directly if server is not working
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())
214 return PMINFO_R_ERROR;
215 // TODO: deliver rawdata to reqhandler directly if server is not working
217 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
218 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
219 client.GetResultParcel()));
220 tizen_base::Parcel parcel;
221 parcel.ReadParcelable(return_parcel.get());
224 // result_list is vector of string vector
225 auto result_list = return_parcel->GetResult();
226 if (result_list.size() == 0)
227 return PMINFO_R_ENOENT;
228 for (auto result : result_list) {
229 if (result.size() != 1)
230 return PMINFO_R_ERROR;
231 if (result.front().empty() || result.front().size() == 0)
232 return PMINFO_R_ERROR;
233 *appid = strdup(result.front().c_str());
234 if (*appid == nullptr) {
235 LOG(ERROR) << "Out of memory";
236 return PMINFO_R_ERROR;
243 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
244 const char *providerid, const char *type, uid_t uid,
245 char **appid, char **trusted) {
246 char *query = nullptr;
247 query = sqlite3_mprintf(
248 "SELECT app_id, trusted FROM package_app_data_control "
249 "WHERE providerid=%Q AND type=%Q", providerid, type);
251 LOGE("Out of memory");
252 return PMINFO_R_ERROR;
255 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
256 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
258 pkgmgr_client::PkgInfoClient client(parcelable, uid,
259 pkgmgr_common::ReqType::QUERY);
260 if (!client.SendRequest())
261 return PMINFO_R_ERROR;
262 // TODO: deliver rawdata to reqhandler directly if server is not working
264 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
265 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
266 client.GetResultParcel()));
267 tizen_base::Parcel parcel;
268 parcel.ReadParcelable(return_parcel.get());
270 // result_list is vector of string vector
271 auto result_list = return_parcel->GetResult();
272 if (result_list.size() == 0)
273 return PMINFO_R_ENOENT;
274 for (auto result : result_list) {
275 if (result.size() != 2)
276 return PMINFO_R_ERROR;
277 if (result.front().empty() || result.front().size() == 0 ||
278 result.back().empty() || result.back().size() == 0)
279 return PMINFO_R_ERROR;
280 *appid = strdup(result.front().c_str());
281 *trusted = strdup(result.back().c_str());
282 if (*appid == nullptr || *trusted == nullptr) {
283 LOG(ERROR) << "Out of memory";
284 return PMINFO_R_ERROR;
291 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
292 const char *providerid, const char *type, uid_t uid,
293 GList **privileges) {
294 char *query = nullptr;
295 query = sqlite3_mprintf(
296 "SELECT privilege FROM package_app_data_control_privilege "
297 "WHERE providerid=%Q AND type=%Q", providerid, type);
299 LOGE("Out of memory");
300 return PMINFO_R_ERROR;
303 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
304 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
306 pkgmgr_client::PkgInfoClient client(parcelable, uid,
307 pkgmgr_common::ReqType::QUERY);
308 if (!client.SendRequest())
309 return PMINFO_R_ERROR;
310 // TODO: deliver rawdata to reqhandler directly if server is not working
312 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
313 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
314 client.GetResultParcel()));
315 tizen_base::Parcel parcel;
316 parcel.ReadParcelable(return_parcel.get());
318 // result_list is vector of string vector
319 auto result_list = return_parcel->GetResult();
320 if (result_list.size() == 0)
321 return PMINFO_R_ENOENT;
323 for (auto result : result_list) {
324 if (result.size() != 1)
325 return PMINFO_R_ERROR;
326 if (result.front().empty() || result.front().size() == 0)
327 return PMINFO_R_ERROR;
328 char *privilege = strdup(result.front().c_str());
329 if (privilege == nullptr) {
330 LOG(ERROR) << "Out of memory";
331 return PMINFO_R_ERROR;
333 *privileges = g_list_append(*privileges, privilege);
339 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
340 const char *appid, const char *operation, uid_t uid, GList **privileges) {
341 char *query = nullptr;
342 query = sqlite3_mprintf(
343 "SELECT app_control, privilege FROM package_app_app_control_privilege "
344 "WHERE app_id=%Q", appid);
346 LOG(ERROR) << "Out of memory";
347 return PMINFO_R_ERROR;
350 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
351 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
353 pkgmgr_client::PkgInfoClient client(parcelable, uid,
354 pkgmgr_common::ReqType::QUERY);
355 if (!client.SendRequest())
356 return PMINFO_R_ERROR;
357 // TODO: deliver rawdata to reqhandler directly if server is not working
359 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
360 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
361 client.GetResultParcel()));
362 tizen_base::Parcel parcel;
363 parcel.ReadParcelable(return_parcel.get());
365 // result_list is vector of string vector
366 auto result_list = return_parcel->GetResult();
367 if (result_list.size() == 0)
368 return PMINFO_R_ENOENT;
370 for (auto result : result_list) {
371 if (result.size() != 2)
372 return PMINFO_R_ERROR;
373 if (result.front().empty() || result.front().size() == 0 ||
374 result.back().empty() || result.back().size() == 0)
375 return PMINFO_R_ERROR;
376 std::string app_control = result.front();
377 std::stringstream ss(app_control);
379 while (std::getline(ss, token, '|')) {
380 if (token.compare(std::string(operation))) {
381 char *privilege = strdup(result.back().c_str());
382 if (privilege == nullptr) {
383 LOG(ERROR) << "Out of memory";
384 return PMINFO_R_ERROR;
386 *privileges = g_list_append(*privileges, privilege);