Change pkgmgrinfo_plugininfo_foreach_plugininfo to use PkgInfoClient
[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                 return label;
144         }
145
146         return label;
147 }
148
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;
159         }
160
161         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
162                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
163
164         pkgmgr_client::PkgInfoClient client(parcelable, uid,
165                         pkgmgr_common::ReqType::QUERY);
166         if (!client.SendRequest()) {
167                 sqlite3_free(query);
168                 return PMINFO_R_ERROR;
169         }
170
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());
176         sqlite3_free(query);
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;
192                 }
193         }
194
195         return PMINFO_R_OK;
196 }
197
198 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
199                 const char *providerid, uid_t uid, char **appid) {
200         char *query = nullptr;
201
202         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
203                 "WHERE providerid=%Q", providerid);
204         if (query == NULL) {
205                 LOGE("Out of memory");
206                 return PMINFO_R_ERROR;
207         }
208         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
209                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
210
211         pkgmgr_client::PkgInfoClient client(parcelable, uid,
212                         pkgmgr_common::ReqType::QUERY);
213         if (!client.SendRequest()) {
214                 sqlite3_free(query);
215                 return PMINFO_R_ERROR;
216         }
217         // TODO: deliver rawdata to reqhandler directly if server is not working
218
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());
224         sqlite3_free(query);
225
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;
239                 }
240         }
241
242         return PMINFO_R_OK;
243 }
244
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);
252         if (query == NULL) {
253                 LOGE("Out of memory");
254                 return PMINFO_R_ERROR;
255         }
256
257         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
258                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
259
260         pkgmgr_client::PkgInfoClient client(parcelable, uid,
261                         pkgmgr_common::ReqType::QUERY);
262         if (!client.SendRequest()) {
263                 sqlite3_free(query);
264                 return PMINFO_R_ERROR;
265         }
266         // TODO: deliver rawdata to reqhandler directly if server is not working
267
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());
273         sqlite3_free(query);
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;
289                 }
290         }
291
292         return PMINFO_R_OK;
293 }
294
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);
302         if (query == NULL) {
303                 LOGE("Out of memory");
304                 return PMINFO_R_ERROR;
305         }
306
307         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
308                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
309
310         pkgmgr_client::PkgInfoClient client(parcelable, uid,
311                         pkgmgr_common::ReqType::QUERY);
312         if (!client.SendRequest()) {
313                 sqlite3_free(query);
314                 return PMINFO_R_ERROR;
315         }
316         // TODO: deliver rawdata to reqhandler directly if server is not working
317
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());
323         sqlite3_free(query);
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;
328
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;
338                 }
339                 *privileges = g_list_append(*privileges, privilege);
340         }
341
342         return PMINFO_R_OK;
343 }
344
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);
351         if (query == NULL) {
352                 LOG(ERROR) << "Out of memory";
353                 return PMINFO_R_ERROR;
354         }
355
356         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
357                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
358
359         pkgmgr_client::PkgInfoClient client(parcelable, uid,
360                         pkgmgr_common::ReqType::QUERY);
361         if (!client.SendRequest()) {
362                 sqlite3_free(query);
363                 return PMINFO_R_ERROR;
364         }
365         // TODO: deliver rawdata to reqhandler directly if server is not working
366
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());
372         sqlite3_free(query);
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;
377
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);
386                 std::string token;
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;
393                                 }
394                                 *privileges = g_list_append(*privileges, privilege);
395                         }
396                 }
397         }
398         return PMINFO_R_OK;
399 }
400
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;
407         }
408
409         char *query = nullptr;
410         query = sqlite3_mprintf(
411                         "SELECT appid FROM "
412                         "package_plugin_info WHERE pkgid=%Q AND "
413                         "plugin_type=%Q AND plugin_name=%Q",
414       pkgid, plugin_type, plugin_name);
415         if (query == NULL) {
416                 LOG(ERROR) << "Out of memory";
417                 return PMINFO_R_ERROR;
418         }
419
420         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
421                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query)));
422         sqlite3_free(query);
423
424         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
425                         pkgmgr_common::ReqType::QUERY);
426         if (!client.SendRequest()) {
427                 return PMINFO_R_ERROR;
428         }
429
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;
436   }
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;
441
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;
447     }
448     *list = g_list_append(*list, strdup(result[0].c_str()));
449   }
450
451   return PMINFO_R_OK;
452 }