2 * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <bundle_cpp.h>
18 #include <bundle_internal.h>
26 #include "include/aul.h"
27 #include "include/aul_app_com.h"
28 #include "include/aul_cmd.h"
33 class AppComConnection {
35 AppComConnection(std::string endpoint, app_com_cb cb, void* user_data)
36 : endpoint_(std::move(endpoint)),
38 user_data_(user_data) {
41 ~AppComConnection() = default;
43 const std::string& GetEndpoint() const {
51 bool IsDisabled() const {
55 void Invoke(aul_app_com_result_e result, bundle* envelope) {
56 if (!disabled_ && cb_)
57 cb_(endpoint_.c_str(), result, envelope, user_data_);
61 bool disabled_ = false;
62 std::string endpoint_;
67 class AppComPermission {
69 AppComPermission() : option_(AUL_APP_COM_PUBLIC) {}
70 ~AppComPermission() {}
72 void SetPrivilege(std::string privilege) {
73 privilege_ = std::move(privilege);
76 void SetPropagationOption(aul_app_com_propagate_option_e option) {
80 const std::string& GetPrivilege() const {
84 aul_app_com_propagate_option_e GetPropagationOption() const {
89 std::string privilege_;
90 aul_app_com_propagate_option_e option_;
98 int Receive(bundle* b) {
99 const char* val = bundle_get_val(b, AUL_K_COM_ENDPOINT);
103 size_t result_size = 0;
104 aul_app_com_result_e* result = nullptr;
105 int ret = bundle_get_byte(b, AUL_K_COM_RESULT,
106 reinterpret_cast<void**>(&result), &result_size);
107 if (ret != BUNDLE_ERROR_NONE)
110 std::string endpoint(val);
112 std::lock_guard<std::recursive_mutex> lock(mutex_);
113 auto iter = conns_.begin();
114 while (iter != conns_.end()) {
117 if (conn->GetEndpoint() == endpoint)
118 conn->Invoke(*result, b);
124 AppComConnection* AddConnection(std::string endpoint, app_com_cb cb,
126 auto* conn = new (std::nothrow) AppComConnection(endpoint, cb, user_data);
130 std::lock_guard<std::recursive_mutex> lock(mutex_);
131 conns_.emplace_back(conn);
135 void RemoveConnection(AppComConnection* conn) {
136 std::lock_guard<std::recursive_mutex> lock(mutex_);
137 auto iter = conns_.begin();
138 while (iter != conns_.end()) {
139 if ((*iter).get() == conn) {
140 iter = conns_.erase(iter);
148 bool ExistConnection(const std::string& endpoint) {
149 std::lock_guard<std::recursive_mutex> lock(mutex_);
150 for (auto& conn : conns_) {
151 if (conn->GetEndpoint() == endpoint && !conn->IsDisabled())
158 bool ExistConnection(AppComConnection* conn) {
159 std::lock_guard<std::recursive_mutex> lock(mutex_);
160 if (conn->IsDisabled())
163 for (auto& i : conns_) {
171 std::recursive_mutex& GetMutex() const {
176 std::list<std::unique_ptr<AppComConnection>> conns_;
177 mutable std::recursive_mutex mutex_;
184 int app_com_recv(bundle* b) {
188 return context.Receive(b);
191 extern "C" API aul_app_com_permission_h aul_app_com_permission_create() {
192 auto* handle = new (std::nothrow) AppComPermission();
193 return static_cast<aul_app_com_permission_h>(handle);
196 extern "C" API void aul_app_com_permission_destroy(
197 aul_app_com_permission_h permission) {
198 if (permission == nullptr)
201 auto* handle = static_cast<AppComPermission*>(permission);
205 extern "C" API int aul_app_com_permission_set_propagation(
206 aul_app_com_permission_h permission,
207 aul_app_com_propagate_option_e option) {
208 if (permission == nullptr)
211 auto* handle = static_cast<AppComPermission*>(permission);
212 handle->SetPropagationOption(option);
216 extern "C" API int aul_app_com_permission_set_privilege(
217 aul_app_com_permission_h permission, const char* privilege) {
218 if (permission == nullptr || privilege == nullptr)
221 auto* handle = static_cast<AppComPermission*>(permission);
222 handle->SetPrivilege(privilege);
226 static int AppComCreate(const char* endpoint,
227 aul_app_com_permission_h permission, app_com_cb callback, void* user_data,
228 bool sync, aul_app_com_connection_h* connection) {
229 if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
230 _E("Invalid parameter");
234 if (!aul_is_initialized()) {
235 if (aul_launch_init(nullptr, nullptr) < 0)
236 return AUL_R_ENOINIT;
239 tizen_base::Bundle b;
240 b.Add(AUL_K_COM_ENDPOINT, endpoint);
243 auto* handle = static_cast<AppComPermission*>(permission);
244 auto option = handle->GetPropagationOption();
246 auto* p = reinterpret_cast<unsigned char*>(&option);
247 std::vector<unsigned char> bytes;
248 std::copy(p, p + sizeof(option), std::back_inserter(bytes));
249 b.Add(AUL_K_COM_PROPAGATE, bytes);
252 if (!handle->GetPrivilege().empty())
253 b.Add(AUL_K_COM_PRIVILEGE, handle->GetPrivilege());
258 ret = app_send_cmd(AUL_UTIL_PID, APP_COM_CREATE, b.GetHandle());
260 ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_COM_CREATE,
265 *connection = static_cast<aul_app_com_connection_h>(
266 context.AddConnection(endpoint, callback, user_data));
272 extern "C" API int aul_app_com_create(const char* endpoint,
273 aul_app_com_permission_h permission, app_com_cb callback,
274 void* user_data, aul_app_com_connection_h* connection) {
275 return AppComCreate(endpoint, permission, callback, user_data,
279 extern "C" API int aul_app_com_create_async(const char* endpoint,
280 aul_app_com_permission_h permission, app_com_cb callback,
281 void* user_data, aul_app_com_connection_h* connection) {
282 return AppComCreate(endpoint, permission, callback, user_data,
286 extern "C" API int aul_app_com_join(const char* endpoint, const char* filter,
287 app_com_cb callback, void* user_data,
288 aul_app_com_connection_h* connection) {
289 if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
290 _E("Invalid parameter");
294 if (!aul_is_initialized()) {
295 if (aul_launch_init(nullptr, nullptr) < 0)
296 return AUL_R_ENOINIT;
299 tizen_base::Bundle b;
300 b.Add(AUL_K_COM_ENDPOINT, endpoint);
302 b.Add(AUL_K_COM_FILTER, filter);
304 int ret = app_send_cmd(AUL_UTIL_PID, APP_COM_JOIN, b.GetHandle());
306 *connection = static_cast<aul_app_com_connection_h>(
307 context.AddConnection(endpoint, callback, user_data));
313 extern "C" API int aul_app_com_send(const char* endpoint, bundle* envelope) {
314 if (endpoint == nullptr || envelope == nullptr)
317 bundle_del(envelope, AUL_K_COM_ENDPOINT);
318 bundle_add(envelope, AUL_K_COM_ENDPOINT, endpoint);
319 return app_send_cmd(AUL_UTIL_PID, APP_COM_SEND, envelope);
322 extern "C" API int aul_app_com_leave(aul_app_com_connection_h connection) {
323 if (connection == nullptr)
326 auto* conn = static_cast<AppComConnection*>(connection);
327 if (!context.ExistConnection(conn)) {
328 _E("Invalid parameter");
332 std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
334 std::string endpoint = conn->GetEndpoint();
335 g_idle_add_full(G_PRIORITY_HIGH, [](gpointer user_data) -> gboolean {
336 auto* conn = static_cast<AppComConnection*>(user_data);
337 context.RemoveConnection(conn);
338 return G_SOURCE_REMOVE;
339 }, connection, nullptr);
341 if (context.ExistConnection(endpoint))
344 tizen_base::Bundle b;
345 b.Add(AUL_K_COM_ENDPOINT, endpoint);
346 return app_send_cmd(AUL_UTIL_PID, APP_COM_LEAVE, b.GetHandle());