137cc5061e6bee7a70bc74f22a2853ad41186519
[platform/core/security/krate.git] / lib / krate / app-proxy.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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 <cstdlib>
18 #include <cstring>
19
20 #include "debug.h"
21 #include "krate.h"
22 #include "app-proxy.h"
23 #include "app-info-internal.h"
24
25 #include "client.h"
26 #include "rmi/app-proxy.h"
27
28 using namespace Krate;
29
30 struct krate_app_proxy_s {
31         Krate::AppProxy proxy;
32         std::string krateName;
33 };
34
35 static inline krate_app_proxy_s* getInstance(krate_app_proxy_h handle)
36 {
37         return reinterpret_cast<krate_app_proxy_s *>(handle);
38 }
39
40 static app_info_h make_app_info_handle(const Krate::AppProxy::AppInfo& info)
41 {
42         if (info.id.empty()) {
43                 return NULL;
44         }
45
46         application_x* app = (application_x*)::calloc(1, sizeof(application_x));
47         if (app == NULL) {
48                 return NULL;
49         }
50
51         pkgmgr_appinfo_x* pkgappinfo = (pkgmgr_appinfo_x*)::calloc(1, sizeof(pkgmgr_appinfo_x));
52         if (pkgappinfo == NULL) {
53                 free(app);
54                 return NULL;
55         }
56
57         app_info_s* appinfo = (app_info_s*)::calloc(1, sizeof(struct app_info_s));
58         if (appinfo == NULL) {
59                 free(app);
60                 free(pkgappinfo);
61                 return NULL;
62         }
63
64         appinfo->app_id = ::strdup(info.id.c_str());
65         appinfo->pkg_app_info = pkgappinfo;
66
67         pkgappinfo->package = ::strdup(info.package.c_str());
68         pkgappinfo->locale = ::strdup(info.locale.c_str());
69         pkgappinfo->app_component = info.componentType;
70         pkgappinfo->app_info = app;
71
72         app->appid = ::strdup(info.id.c_str());
73         app->nodisplay = ::strdup(info.isNoDisplayed? "true":"false");
74         app->taskmanage = ::strdup(info.isTaskManaged? "true":"false");
75         app->type = ::strdup(info.type.c_str());
76
77         icon_x* icon = (icon_x*)::calloc(1, sizeof(icon_x));
78         if (icon != NULL) {
79                 icon->text = ::strdup(info.icon.c_str());
80                 icon->lang = ::strdup(info.locale.c_str());
81                 app->icon = ::g_list_append(NULL, icon);
82         }
83
84         label_x* label = (label_x*)::calloc(1, sizeof(label_x));
85         if (label != NULL) {
86                 label->text = ::strdup(info.label.c_str());
87                 label->lang = ::strdup(info.locale.c_str());
88                 app->label = ::g_list_append(NULL, label);
89         }
90
91         return reinterpret_cast<app_info_h>(appinfo);
92 }
93
94 int krate_app_proxy_create(krate_manager_h manager, const char* name, krate_app_proxy_h *handle)
95 {
96         RET_ON_FAILURE(manager, KRATE_ERROR_INVALID_PARAMETER);
97         RET_ON_FAILURE(name, KRATE_ERROR_INVALID_PARAMETER);
98         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
99
100         krate_app_proxy_s* instance = new krate_app_proxy_s {
101                 GetKrateContext(manager).createKrateInterface<Krate::AppProxy>(),
102                 name
103         };
104
105         *handle = reinterpret_cast<krate_app_proxy_h>(instance);
106         return KRATE_ERROR_NONE;
107 }
108
109 int krate_app_proxy_destroy(krate_app_proxy_h handle)
110 {
111         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
112
113         delete reinterpret_cast<Krate::AppProxy*>(handle);
114
115         return KRATE_ERROR_NONE;
116 }
117
118 int krate_app_proxy_get_app_info(krate_app_proxy_h handle, const char* app_id, app_info_h* app_info)
119 {
120         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
121         RET_ON_FAILURE(app_id, KRATE_ERROR_INVALID_PARAMETER);
122         RET_ON_FAILURE(app_info, KRATE_ERROR_INVALID_PARAMETER);
123
124         auto instance = getInstance(handle);
125         auto& proxy = instance->proxy;
126         const std::string& name = instance->krateName;
127
128         const auto info = proxy.getAppInfo(name, app_id);
129         app_info_h ret = make_app_info_handle(info);
130         if (ret == NULL) {
131                 return KRATE_ERROR_INVALID_PARAMETER;
132         }
133
134         *app_info = ret;
135
136         return KRATE_ERROR_NONE;
137 }
138
139 int krate_app_proxy_foreach_app_info(krate_app_proxy_h handle, app_manager_app_info_cb callback, void *user_data)
140 {
141         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
142         RET_ON_FAILURE(callback, KRATE_ERROR_INVALID_PARAMETER);
143
144         auto instance = getInstance(handle);
145         auto& proxy = instance->proxy;
146         const std::string& name = instance->krateName;
147
148         int iter = proxy.createIterator(name);
149         do {
150                 app_info_h info = make_app_info_handle(proxy.getIteratorValue(iter));
151                 int ret = callback(info, user_data);
152                 app_info_destroy(info);
153                 if (!ret) {
154                         break;
155                 }
156         } while (proxy.nextIterator(iter));
157         proxy.destroyIterator(iter);
158
159         return KRATE_ERROR_NONE;
160 }
161
162 static bool appExtraCallback(app_control_h app_control, const char *key, void *user_data)
163 {
164         Krate::AppProxy::Bundle *bundle = reinterpret_cast<Krate::AppProxy::Bundle*>(user_data);
165         Krate::AppProxy::Bundle::Extra extra;
166         bool isArray;
167
168         extra.key = key;
169
170         app_control_is_extra_data_array(app_control, key, &isArray);
171         if (isArray) {
172                 char **values;
173                 int length = 0;
174                 app_control_get_extra_data_array(app_control, key, &values, &length);
175                 for (int i = 0; i < length; i++) {
176                         extra.value.push_back(values[i]);
177                         free(values[i]);
178                 }
179                 free(values);
180         } else {
181                 char *value;
182                 app_control_get_extra_data(app_control, key, &value);
183                 extra.value.push_back(value);
184                 free(value);
185         }
186         bundle->extraData.push_back(extra);
187
188         return true;
189 }
190
191 int krate_app_proxy_send_launch_request(krate_app_proxy_h handle, app_control_h app_control)
192 {
193         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
194         RET_ON_FAILURE(app_control, KRATE_ERROR_INVALID_PARAMETER);
195
196         auto instance = getInstance(handle);
197         auto& proxy = instance->proxy;
198         const std::string& name = instance->krateName;
199         char *str;
200
201         Krate::AppProxy::Bundle bundle;
202         app_control_get_operation(app_control, &str);
203         if (str != NULL) {
204                 bundle.operation = str;
205                 free(str);
206                 str = NULL;
207         }
208         app_control_get_uri(app_control, &str);
209         if (str != NULL) {
210                 bundle.uri = str;
211                 free(str);
212                 str = NULL;
213         }
214         app_control_get_mime(app_control, &str);
215         if (str != NULL) {
216                 bundle.mime = str;
217                 free(str);
218                 str = NULL;
219         }
220         app_control_get_category(app_control, &str);
221         if (str != NULL) {
222                 bundle.category = str;
223                 free(str);
224                 str = NULL;
225         }
226         app_control_get_app_id(app_control, &str);
227         if (str != NULL) {
228                 bundle.appId = str;
229                 free(str);
230                 str = NULL;
231         }
232         app_control_foreach_extra_data(app_control, appExtraCallback, &bundle);
233
234         return proxy.launch(name, bundle);
235 }
236
237 int krate_app_proxy_terminate(krate_app_proxy_h handle, const char* app_id)
238 {
239         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
240         RET_ON_FAILURE(app_id, KRATE_ERROR_INVALID_PARAMETER);
241
242         auto instance = getInstance(handle);
243         auto& proxy = instance->proxy;
244         const std::string& name = instance->krateName;
245
246         return proxy.terminate(name, app_id);
247 }
248
249 int krate_app_proxy_resume(krate_app_proxy_h handle, const char* app_id)
250 {
251         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
252         RET_ON_FAILURE(app_id, KRATE_ERROR_INVALID_PARAMETER);
253
254         auto instance = getInstance(handle);
255         auto& proxy = instance->proxy;
256         const std::string& name = instance->krateName;
257
258         return proxy.resume(name, app_id);
259 }
260
261 int krate_app_proxy_is_running(krate_app_proxy_h handle, const char* app_id, int *result)
262 {
263         RET_ON_FAILURE(handle, KRATE_ERROR_INVALID_PARAMETER);
264         RET_ON_FAILURE(app_id, KRATE_ERROR_INVALID_PARAMETER);
265         RET_ON_FAILURE(result, KRATE_ERROR_INVALID_PARAMETER);
266
267         auto instance = getInstance(handle);
268         auto& proxy = instance->proxy;
269         const std::string& name = instance->krateName;
270
271         *result = proxy.isRunning(name, app_id);
272         return KRATE_ERROR_NONE;
273 }