Update pkgmgr-info APIs
[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 "sqlite3.h"
22 #include "glib.h"
23
24 #include "pkgmgrinfo_private.h"
25
26 #include "logging.hh"
27 #include "common/parcel/appinfo_parcelable.hh"
28 #include "common/parcel/filter_parcelable.hh"
29 #include "common/parcel/pkginfo_parcelable.hh"
30 #include "common/parcel/query_parcelable.hh"
31 #include "common/parcel/result_parcelable.hh"
32
33 #include "client/pkginfo_client.hh"
34
35 #include <parcel.hh>
36
37 #ifdef LOG_TAG
38 #undef LOG_TAG
39 #endif
40 #define LOG_TAG "PKGMGR_INFO"
41
42 #ifdef EXPORT_API
43 #undef EXPORT_API
44 #endif
45 #define EXPORT_API __attribute__((visibility("default")))
46
47 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
48             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) { 
49         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
50                         new pkgmgr_common::parcel::FilterParcelable(uid,
51                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
52
53         pkgmgr_client::PkgInfoClient client(parcelable, uid);
54         if (!client.SendRequest())
55       return PMINFO_R_ERROR;
56
57         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
58                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
59                                         client.GetResultParcel()));
60
61         tizen_base::Parcel parcel;
62         parcel.ReadParcelable(return_parcel.get());
63
64         auto result_list = return_parcel->GetPkgInfo();
65         // TODO: check noentry error has returned if size of result_list is 0
66         for (auto& pkginfo : result_list) {
67                 g_hash_table_insert(packages, (gpointer)pkginfo->package, (gpointer)pkginfo);
68                 // TODO: remove element from list. is this work?
69                 pkginfo = nullptr;      
70         }
71
72         return PMINFO_R_OK;
73 }
74
75 // TODO: Need to add target db uid to identify which database to be searched
76 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
77                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
78         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
79                         new pkgmgr_common::parcel::FilterParcelable(uid,
80                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
81
82         pkgmgr_client::PkgInfoClient client(parcelable, uid);
83         if (!client.SendRequest())
84       return PMINFO_R_ERROR;
85
86         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
87                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
88                                         client.GetResultParcel()));
89
90         tizen_base::Parcel parcel;
91         parcel.ReadParcelable(return_parcel.get());
92         auto result_list = return_parcel->GetAppInfo();
93         for (auto& appinfo : result_list) {
94                 g_hash_table_insert(packages, (gpointer)appinfo->appid, (gpointer)appinfo);
95                 // TODO: remove element from list. is this work?
96                 appinfo = nullptr;      
97         }
98
99         return PMINFO_R_OK;
100 }
101
102 extern "C" EXPORT_API char *_appinfo_get_localed_label(
103                 const char *appid, const char *locale, uid_t uid) {
104         char *query = nullptr;
105     query = sqlite3_mprintf(
106                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
107                         "WHERE app_id=%Q AND app_locale=%Q),"
108                         "(SELECT app_label FROM package_app_localized_info WHERE "
109                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
110         if (query == nullptr) {
111                 LOG(ERROR) << "Out of memory";
112                 return nullptr;
113         }
114
115         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
116                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
117
118         pkgmgr_client::PkgInfoClient client(parcelable, uid);
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 int _appinfo_get_datacontrol_info(const char *providerid, 
147                 const char *type, uid_t uid, char **appid, char **access) {
148         char *query = nullptr;
149         query = sqlite3_mprintf("SELECT app_id, access FROM "
150                         "package_app_data_control WHERE "
151                         "providerid=%Q AND type=%Q", providerid, type);
152         if (query == nullptr) {
153                 LOG(ERROR) << "Out of memory";
154                 return PMINFO_R_ERROR;
155         }
156
157         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
158                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
159
160         pkgmgr_client::PkgInfoClient client(parcelable, uid);
161         if (!client.SendRequest())
162                 return PMINFO_R_ERROR;
163         // TODO: deliver rawdata to reqhandler directly if server is not working
164
165         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
166                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
167                                         client.GetResultParcel()));
168         tizen_base::Parcel parcel;
169         parcel.ReadParcelable(return_parcel.get());
170         sqlite3_free(query);
171         // result_list is vector of string vector
172         auto result_list = return_parcel->GetResult();
173         if (result_list.size() == 0)
174                 return PMINFO_R_ENOENT;
175         for (auto result : result_list) {
176                 if (result.size() != 2)
177                         return PMINFO_R_ERROR;
178                 if (result.front().empty() || result.front().size() == 0 ||
179                                 result.back().empty() || result.back().size() == 0)
180                         return PMINFO_R_ERROR;
181                 *appid = strdup(result.front().c_str());
182                 *access = strdup(result.back().c_str());
183                 if (*appid == nullptr || *access == nullptr) {
184                         LOG(ERROR) << "Out of memory";
185                         return PMINFO_R_ERROR;
186                 }
187         }
188
189         return PMINFO_R_OK;
190 }