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 if (!client.SendRequest())
57 return PMINFO_R_ERROR;
59 std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
60 std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
61 client.GetResultParcel()));
63 tizen_base::Parcel parcel;
64 parcel.ReadParcelable(return_parcel.get());
66 auto result_list = return_parcel->GetPkgInfo();
67 // TODO: check noentry error has returned if size of result_list is 0
68 for (auto& pkginfo : result_list) {
69 g_hash_table_insert(packages, (gpointer)pkginfo->package, (gpointer)pkginfo);
70 // TODO: remove element from list. is this work?
77 // TODO: Need to add target db uid to identify which database to be searched
78 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
79 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
80 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
81 new pkgmgr_common::parcel::FilterParcelable(uid,
82 static_cast<pkgmgrinfo_filter_x*>(filter), flag));
84 pkgmgr_client::PkgInfoClient client(parcelable, uid);
85 if (!client.SendRequest())
86 return PMINFO_R_ERROR;
88 std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
89 std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
90 client.GetResultParcel()));
92 tizen_base::Parcel parcel;
93 parcel.ReadParcelable(return_parcel.get());
94 auto result_list = return_parcel->GetAppInfo();
95 for (auto& appinfo : result_list) {
96 g_hash_table_insert(packages, (gpointer)appinfo->appid, (gpointer)appinfo);
97 // TODO: remove element from list. is this work?
104 extern "C" EXPORT_API char *_appinfo_get_localed_label(
105 const char *appid, const char *locale, uid_t uid) {
106 char *query = nullptr;
107 query = sqlite3_mprintf(
108 "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
109 "WHERE app_id=%Q AND app_locale=%Q),"
110 "(SELECT app_label FROM package_app_localized_info WHERE "
111 "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
112 if (query == nullptr) {
113 LOG(ERROR) << "Out of memory";
117 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
118 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
120 pkgmgr_client::PkgInfoClient client(parcelable, uid);
121 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
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 if (!client.SendRequest())
165 return PMINFO_R_ERROR;
166 // TODO: deliver rawdata to reqhandler directly if server is not working
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 if (!client.SendRequest())
210 return PMINFO_R_ERROR;
211 // TODO: deliver rawdata to reqhandler directly if server is not working
213 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
214 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
215 client.GetResultParcel()));
216 tizen_base::Parcel parcel;
217 parcel.ReadParcelable(return_parcel.get());
220 // result_list is vector of string vector
221 auto result_list = return_parcel->GetResult();
222 if (result_list.size() == 0)
223 return PMINFO_R_ENOENT;
224 for (auto result : result_list) {
225 if (result.size() != 1)
226 return PMINFO_R_ERROR;
227 if (result.front().empty() || result.front().size() == 0)
228 return PMINFO_R_ERROR;
229 *appid = strdup(result.front().c_str());
230 if (*appid == nullptr) {
231 LOG(ERROR) << "Out of memory";
232 return PMINFO_R_ERROR;
239 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
240 const char *providerid, const char *type, uid_t uid,
241 char **appid, char **trusted) {
242 char *query = nullptr;
243 query = sqlite3_mprintf(
244 "SELECT app_id, trusted FROM package_app_data_control "
245 "WHERE providerid=%Q AND type=%Q", providerid, type);
247 LOGE("Out of memory");
248 return PMINFO_R_ERROR;
251 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
252 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
254 pkgmgr_client::PkgInfoClient client(parcelable, uid);
255 if (!client.SendRequest())
256 return PMINFO_R_ERROR;
257 // TODO: deliver rawdata to reqhandler directly if server is not working
259 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
260 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
261 client.GetResultParcel()));
262 tizen_base::Parcel parcel;
263 parcel.ReadParcelable(return_parcel.get());
265 // result_list is vector of string vector
266 auto result_list = return_parcel->GetResult();
267 if (result_list.size() == 0)
268 return PMINFO_R_ENOENT;
269 for (auto result : result_list) {
270 if (result.size() != 2)
271 return PMINFO_R_ERROR;
272 if (result.front().empty() || result.front().size() == 0 ||
273 result.back().empty() || result.back().size() == 0)
274 return PMINFO_R_ERROR;
275 *appid = strdup(result.front().c_str());
276 *trusted = strdup(result.back().c_str());
277 if (*appid == nullptr || *trusted == nullptr) {
278 LOG(ERROR) << "Out of memory";
279 return PMINFO_R_ERROR;
286 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
287 const char *providerid, const char *type, uid_t uid,
288 GList **privileges) {
289 char *query = nullptr;
290 query = sqlite3_mprintf(
291 "SELECT privilege FROM package_app_data_control_privilege "
292 "WHERE providerid=%Q AND type=%Q", providerid, type);
294 LOGE("Out of memory");
295 return PMINFO_R_ERROR;
298 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
299 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
301 pkgmgr_client::PkgInfoClient client(parcelable, uid);
302 if (!client.SendRequest())
303 return PMINFO_R_ERROR;
304 // TODO: deliver rawdata to reqhandler directly if server is not working
306 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
307 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
308 client.GetResultParcel()));
309 tizen_base::Parcel parcel;
310 parcel.ReadParcelable(return_parcel.get());
312 // result_list is vector of string vector
313 auto result_list = return_parcel->GetResult();
314 if (result_list.size() == 0)
315 return PMINFO_R_ENOENT;
317 for (auto result : result_list) {
318 if (result.size() != 1)
319 return PMINFO_R_ERROR;
320 if (result.front().empty() || result.front().size() == 0)
321 return PMINFO_R_ERROR;
322 char *privilege = strdup(result.front().c_str());
323 if (privilege == nullptr) {
324 LOG(ERROR) << "Out of memory";
325 return PMINFO_R_ERROR;
327 *privileges = g_list_append(*privileges, privilege);
333 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
334 const char *appid, const char *operation, uid_t uid, GList **privileges) {
335 char *query = nullptr;
336 query = sqlite3_mprintf(
337 "SELECT app_control, privilege FROM package_app_app_control_privilege "
338 "WHERE app_id=%Q", appid);
340 LOG(ERROR) << "Out of memory";
341 return PMINFO_R_ERROR;
344 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
345 new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
347 pkgmgr_client::PkgInfoClient client(parcelable, uid);
348 if (!client.SendRequest())
349 return PMINFO_R_ERROR;
350 // TODO: deliver rawdata to reqhandler directly if server is not working
352 std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
353 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
354 client.GetResultParcel()));
355 tizen_base::Parcel parcel;
356 parcel.ReadParcelable(return_parcel.get());
358 // result_list is vector of string vector
359 auto result_list = return_parcel->GetResult();
360 if (result_list.size() == 0)
361 return PMINFO_R_ENOENT;
363 for (auto result : result_list) {
364 if (result.size() != 2)
365 return PMINFO_R_ERROR;
366 if (result.front().empty() || result.front().size() == 0 ||
367 result.back().empty() || result.back().size() == 0)
368 return PMINFO_R_ERROR;
369 std::string app_control = result.front();
370 std::stringstream ss(app_control);
372 while (std::getline(ss, token, '|')) {
373 if (token.compare(std::string(operation))) {
374 char *privilege = strdup(result.back().c_str());
375 if (privilege == nullptr) {
376 LOG(ERROR) << "Out of memory";
377 return PMINFO_R_ERROR;
379 *privileges = g_list_append(*privileges, privilege);