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                 sqlite3_free(query);
121                 return nullptr;
122         }
123         
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());
129         sqlite3_free(query);
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)
137                         return nullptr;
138                 label = strdup(result.front().c_str());
139                 if (label == nullptr) {
140                         LOG(ERROR) << "Out of memory";
141                         return nullptr;
142                 }
143         }
144
145         return label;
146 }
147
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;
158         }
159
160         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
161                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
162
163         pkgmgr_client::PkgInfoClient client(parcelable, uid,
164                         pkgmgr_common::ReqType::QUERY);
165         if (!client.SendRequest()) {
166                 sqlite3_free(query);
167                 return PMINFO_R_ERROR;
168         }
169
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());
175         sqlite3_free(query);
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;
191                 }
192         }
193
194         return PMINFO_R_OK;
195 }
196
197 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
198                 const char *providerid, uid_t uid, char **appid) {
199         char *query = nullptr;
200
201         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
202                 "WHERE providerid=%Q", providerid);
203         if (query == NULL) {
204                 LOGE("Out of memory");
205                 return PMINFO_R_ERROR;
206         }
207         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
208                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
209
210         pkgmgr_client::PkgInfoClient client(parcelable, uid,
211                         pkgmgr_common::ReqType::QUERY);
212         if (!client.SendRequest()) {
213                 sqlite3_free(query);
214                 return PMINFO_R_ERROR;
215         }
216         // TODO: deliver rawdata to reqhandler directly if server is not working
217
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());
223         sqlite3_free(query);
224
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;
238                 }
239         }
240
241         return PMINFO_R_OK;
242 }
243
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);
251         if (query == NULL) {
252                 LOGE("Out of memory");
253                 return PMINFO_R_ERROR;
254         }
255
256         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
257                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
258
259         pkgmgr_client::PkgInfoClient client(parcelable, uid,
260                         pkgmgr_common::ReqType::QUERY);
261         if (!client.SendRequest()) {
262                 sqlite3_free(query);
263                 return PMINFO_R_ERROR;
264         }
265         // TODO: deliver rawdata to reqhandler directly if server is not working
266
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());
272         sqlite3_free(query);
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;
288                 }
289         }
290
291         return PMINFO_R_OK;
292 }
293
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);
301         if (query == NULL) {
302                 LOGE("Out of memory");
303                 return PMINFO_R_ERROR;
304         }       
305
306         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
307                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
308
309         pkgmgr_client::PkgInfoClient client(parcelable, uid,
310                         pkgmgr_common::ReqType::QUERY);
311         if (!client.SendRequest()) {
312                 sqlite3_free(query);
313                 return PMINFO_R_ERROR;
314         }
315         // TODO: deliver rawdata to reqhandler directly if server is not working
316
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());
322         sqlite3_free(query);
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;
327         
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;
337                 }
338                 *privileges = g_list_append(*privileges, privilege);
339         }
340
341         return PMINFO_R_OK;
342 }
343
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);
350         if (query == NULL) {
351                 LOG(ERROR) << "Out of memory";
352                 return PMINFO_R_ERROR;
353         }       
354
355         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
356                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
357
358         pkgmgr_client::PkgInfoClient client(parcelable, uid,
359                         pkgmgr_common::ReqType::QUERY);
360         if (!client.SendRequest()) {
361                 sqlite3_free(query);
362                 return PMINFO_R_ERROR;
363         }
364         // TODO: deliver rawdata to reqhandler directly if server is not working
365
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());
371         sqlite3_free(query);
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;
376         
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);
385                 std::string token;
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;
392                                 }
393                                 *privileges = g_list_append(*privileges, privilege);
394                         }
395                 }
396         }
397         return PMINFO_R_OK;
398 }