Implement getting datacontrol trusted info API
[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 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         if (!client.SendRequest())
163                 return PMINFO_R_ERROR;
164         // TODO: deliver rawdata to reqhandler directly if server is not working
165
166         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
167                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
168                                         client.GetResultParcel()));
169         tizen_base::Parcel parcel;
170         parcel.ReadParcelable(return_parcel.get());
171         sqlite3_free(query);
172         // result_list is vector of string vector
173         auto result_list = return_parcel->GetResult();
174         if (result_list.size() == 0)
175                 return PMINFO_R_ENOENT;
176         for (auto result : result_list) {
177                 if (result.size() != 2)
178                         return PMINFO_R_ERROR;
179                 if (result.front().empty() || result.front().size() == 0 ||
180                                 result.back().empty() || result.back().size() == 0)
181                         return PMINFO_R_ERROR;
182                 *appid = strdup(result.front().c_str());
183                 *access = strdup(result.back().c_str());
184                 if (*appid == nullptr || *access == nullptr) {
185                         LOG(ERROR) << "Out of memory";
186                         return PMINFO_R_ERROR;
187                 }
188         }
189
190         return PMINFO_R_OK;
191 }
192
193 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
194                 const char *providerid, uid_t uid, char **appid) {
195         char *query = nullptr;
196
197         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
198                 "WHERE providerid=%Q", providerid);
199         if (query == NULL) {
200                 LOGE("Out of memory");
201                 return PMINFO_R_ERROR;
202         }
203         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
204                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
205
206         pkgmgr_client::PkgInfoClient client(parcelable, uid);
207         if (!client.SendRequest())
208                 return PMINFO_R_ERROR;
209         // TODO: deliver rawdata to reqhandler directly if server is not working
210
211         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
212                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
213                                         client.GetResultParcel()));
214         tizen_base::Parcel parcel;
215         parcel.ReadParcelable(return_parcel.get());
216         sqlite3_free(query);
217
218         // result_list is vector of string vector
219         auto result_list = return_parcel->GetResult();
220         if (result_list.size() == 0)
221                 return PMINFO_R_ENOENT;
222         for (auto result : result_list) {
223                 if (result.size() != 1)
224                         return PMINFO_R_ERROR;
225                 if (result.front().empty() || result.front().size() == 0)
226                         return PMINFO_R_ERROR;
227                 *appid = strdup(result.front().c_str());
228                 if (*appid == nullptr) {
229                         LOG(ERROR) << "Out of memory";
230                         return PMINFO_R_ERROR;
231                 }
232         }
233
234         return PMINFO_R_OK;
235 }
236
237 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
238                 const char *providerid, const char *type, uid_t uid, 
239                 char **appid, char **trusted) {
240         char *query = nullptr;
241         query = sqlite3_mprintf(
242                         "SELECT app_id, trusted FROM package_app_data_control "
243                         "WHERE providerid=%Q AND type=%Q", providerid, type);
244         if (query == NULL) {
245                 LOGE("Out of memory");
246                 return PMINFO_R_ERROR;
247         }
248
249         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
250                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query)));
251
252         pkgmgr_client::PkgInfoClient client(parcelable, uid);
253         if (!client.SendRequest())
254                 return PMINFO_R_ERROR;
255         // TODO: deliver rawdata to reqhandler directly if server is not working
256
257         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
258                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
259                                         client.GetResultParcel()));
260         tizen_base::Parcel parcel;
261         parcel.ReadParcelable(return_parcel.get());
262         sqlite3_free(query);
263         // result_list is vector of string vector
264         auto result_list = return_parcel->GetResult();
265         if (result_list.size() == 0)
266                 return PMINFO_R_ENOENT;
267         for (auto result : result_list) {
268                 if (result.size() != 2)
269                         return PMINFO_R_ERROR;
270                 if (result.front().empty() || result.front().size() == 0 ||
271                                 result.back().empty() || result.back().size() == 0)
272                         return PMINFO_R_ERROR;
273                 *appid = strdup(result.front().c_str());
274                 *trusted = strdup(result.back().c_str());
275                 if (*appid == nullptr || *trusted == nullptr) {
276                         LOG(ERROR) << "Out of memory";
277                         return PMINFO_R_ERROR;
278                 }
279         }
280
281         return PMINFO_R_OK;
282 }