Fix static analysis issue
[platform/core/appfw/pkgmgr-info.git] / src / manager / pkginfo_manager.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "manager/pkginfo_manager.h"
18
19 #include <sys/types.h>
20
21 #include <string>
22
23 #include "sqlite3.h"
24 #include "glib.h"
25
26 #include "pkgmgrinfo_private.h"
27
28 #include "logging.hh"
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"
34
35 #include "client/pkginfo_client.hh"
36
37 #include <parcel.hh>
38
39 #ifdef LOG_TAG
40 #undef LOG_TAG
41 #endif
42 #define LOG_TAG "PKGMGR_INFO"
43
44 #ifdef EXPORT_API
45 #undef EXPORT_API
46 #endif
47 #define EXPORT_API __attribute__((visibility("default")))
48
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));
54
55         pkgmgr_client::PkgInfoClient client(parcelable, uid, 
56                         pkgmgr_common::ReqType::GET_PKG_INFO);
57         if (!client.SendRequest())
58       return PMINFO_R_ERROR;
59
60         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
61                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
62                                         client.GetResultParcel()));
63
64         tizen_base::Parcel parcel;
65         parcel.ReadParcelable(return_parcel.get());
66
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, 
71                                 (gpointer)pkginfo);
72
73         return PMINFO_R_OK;
74 }
75
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));
82
83         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
84         if (!client.SendRequest())
85       return PMINFO_R_ERROR;
86
87         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
88                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
89                                         client.GetResultParcel()));
90
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,
96                                 (gpointer)appinfo);
97
98         return PMINFO_R_OK;
99 }
100
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";
111                 return nullptr;
112         }
113
114         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
115                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
116
117         pkgmgr_client::PkgInfoClient client(parcelable, uid, 
118                         pkgmgr_common::ReqType::QUERY);
119         if (!client.SendRequest())
120                 return nullptr;
121         sqlite3_free(query);
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());
127         
128         // result_list is vector of string vector
129         char *label;
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)
135                         return nullptr;
136                 label = strdup(result.front().c_str());
137                 if (label == nullptr) {
138                         LOG(ERROR) << "Out of memory";
139                         return nullptr;
140                 }
141         }
142
143         return label;
144 }
145
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;
156         }
157
158         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
159                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
160
161         pkgmgr_client::PkgInfoClient client(parcelable, uid,
162                         pkgmgr_common::ReqType::QUERY);
163         if (!client.SendRequest()) {
164                 sqlite3_free(query);
165                 return PMINFO_R_ERROR;
166         }
167
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());
173         sqlite3_free(query);
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;
189                 }
190         }
191
192         return PMINFO_R_OK;
193 }
194
195 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
196                 const char *providerid, uid_t uid, char **appid) {
197         char *query = nullptr;
198
199         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
200                 "WHERE providerid=%Q", providerid);
201         if (query == NULL) {
202                 LOGE("Out of memory");
203                 return PMINFO_R_ERROR;
204         }
205         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
206                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
207
208         pkgmgr_client::PkgInfoClient client(parcelable, uid,
209                         pkgmgr_common::ReqType::QUERY);
210         if (!client.SendRequest()) {
211                 sqlite3_free(query);
212                 return PMINFO_R_ERROR;
213         }
214         // TODO: deliver rawdata to reqhandler directly if server is not working
215
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());
221         sqlite3_free(query);
222
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;
236                 }
237         }
238
239         return PMINFO_R_OK;
240 }
241
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);
249         if (query == NULL) {
250                 LOGE("Out of memory");
251                 return PMINFO_R_ERROR;
252         }
253
254         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
255                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
256
257         pkgmgr_client::PkgInfoClient client(parcelable, uid,
258                         pkgmgr_common::ReqType::QUERY);
259         if (!client.SendRequest()) {
260                 sqlite3_free(query);
261                 return PMINFO_R_ERROR;
262         }
263         // TODO: deliver rawdata to reqhandler directly if server is not working
264
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());
270         sqlite3_free(query);
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;
286                 }
287         }
288
289         return PMINFO_R_OK;
290 }
291
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);
299         if (query == NULL) {
300                 LOGE("Out of memory");
301                 return PMINFO_R_ERROR;
302         }       
303
304         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
305                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
306
307         pkgmgr_client::PkgInfoClient client(parcelable, uid,
308                         pkgmgr_common::ReqType::QUERY);
309         if (!client.SendRequest()) {
310                 sqlite3_free(query);
311                 return PMINFO_R_ERROR;
312         }
313         // TODO: deliver rawdata to reqhandler directly if server is not working
314
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());
320         sqlite3_free(query);
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;
325         
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;
335                 }
336                 *privileges = g_list_append(*privileges, privilege);
337         }
338
339         return PMINFO_R_OK;
340 }
341
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);
348         if (query == NULL) {
349                 LOG(ERROR) << "Out of memory";
350                 return PMINFO_R_ERROR;
351         }       
352
353         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
354                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
355
356         pkgmgr_client::PkgInfoClient client(parcelable, uid,
357                         pkgmgr_common::ReqType::QUERY);
358         if (!client.SendRequest()) {
359                 sqlite3_free(query);
360                 return PMINFO_R_ERROR;
361         }
362         // TODO: deliver rawdata to reqhandler directly if server is not working
363
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());
369         sqlite3_free(query);
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;
374         
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);
383                 std::string token;
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;
390                                 }
391                                 *privileges = g_list_append(*privileges, privilege);
392                         }
393                 }
394         }
395         return PMINFO_R_OK;
396 }