/*
- * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2015 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
+#include "include/aul_app_com.h"
+
#include <bundle_cpp.h>
#include <bundle_internal.h>
#include <mutex>
#include <string>
+#include "app_request.h"
#include "aul_api.h"
#include "aul_util.h"
#include "include/aul.h"
-#include "include/aul_app_com.h"
#include "include/aul_cmd.h"
#include "launch.h"
+using namespace aul::internal;
+
namespace {
class AppComConnection {
return endpoint_;
}
+ void Disable() {
+ disabled_ = true;
+ }
+
+ bool IsDisabled() const {
+ return disabled_;
+ }
+
void Invoke(aul_app_com_result_e result, bundle* envelope) {
- if (cb_)
+ if (!disabled_ && cb_)
cb_(endpoint_.c_str(), result, envelope, user_data_);
}
private:
+ bool disabled_ = false;
std::string endpoint_;
app_com_cb cb_;
void* user_data_;
class AppComPermission {
public:
- AppComPermission() {}
+ AppComPermission() : option_(AUL_APP_COM_PUBLIC) {}
~AppComPermission() {}
void SetPrivilege(std::string privilege) {
std::string endpoint(val);
std::lock_guard<std::recursive_mutex> lock(mutex_);
- for (auto& conn : conns_) {
+ auto iter = conns_.begin();
+ while (iter != conns_.end()) {
+ auto& conn = *iter;
+ iter++;
if (conn->GetEndpoint() == endpoint)
conn->Invoke(*result, b);
}
bool ExistConnection(const std::string& endpoint) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto& conn : conns_) {
- if (conn->GetEndpoint() == endpoint)
+ if (conn->GetEndpoint() == endpoint && !conn->IsDisabled())
return true;
}
bool ExistConnection(AppComConnection* conn) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (conn->IsDisabled())
+ return false;
+
for (auto& i : conns_) {
if (i.get() == conn)
return true;
return false;
}
+ std::recursive_mutex& GetMutex() const {
+ return mutex_;
+ }
+
private:
std::list<std::unique_ptr<AppComConnection>> conns_;
mutable std::recursive_mutex mutex_;
Context context;
+int AppComCreate(const char* endpoint,
+ aul_app_com_permission_h permission, app_com_cb callback, void* user_data,
+ bool sync, aul_app_com_connection_h* connection) {
+ if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (!aul_is_initialized()) {
+ if (aul_launch_init(nullptr, nullptr) < 0)
+ return AUL_R_ENOINIT;
+ }
+
+ tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
+ if (permission) {
+ auto* handle = static_cast<AppComPermission*>(permission);
+ auto option = handle->GetPropagationOption();
+ if (option) {
+ auto* p = reinterpret_cast<unsigned char*>(&option);
+ std::vector<unsigned char> bytes;
+ std::copy(p, p + sizeof(option), std::back_inserter(bytes));
+ b.Add(AUL_K_COM_PROPAGATE, bytes);
+ }
+
+ if (!handle->GetPrivilege().empty())
+ b.Add(AUL_K_COM_PRIVILEGE, handle->GetPrivilege());
+ }
+
+ int ret = AppRequest(APP_COM_CREATE, getuid())
+ .With(std::move(b))
+ .SendSimply(sync ? AUL_SOCK_NONE : AUL_SOCK_NOREPLY);
+ if (ret == 0) {
+ *connection = static_cast<aul_app_com_connection_h>(
+ context.AddConnection(endpoint, callback, user_data));
+ }
+
+ return ret;
+}
+
} // namespace
int app_com_recv(bundle* b) {
return AUL_R_OK;
}
-static int AppComCreate(const char* endpoint,
- aul_app_com_permission_h permission, app_com_cb callback, void* user_data,
- bool sync, aul_app_com_connection_h* connection) {
- if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
- _E("Invalid parameter");
- return AUL_R_EINVAL;
- }
-
- if (!aul_is_initialized()) {
- if (aul_launch_init(nullptr, nullptr) < 0)
- return AUL_R_ENOINIT;
- }
-
- tizen_base::Bundle b;
- b.Add(AUL_K_COM_ENDPOINT, endpoint);
-
- if (permission) {
- auto* handle = static_cast<AppComPermission*>(permission);
- auto option = handle->GetPropagationOption();
- if (option) {
- auto* p = reinterpret_cast<unsigned char*>(&option);
- std::vector<unsigned char> bytes;
- std::copy(p, p + sizeof(option), std::back_inserter(bytes));
- b.Add(AUL_K_COM_PROPAGATE, bytes);
- }
-
- if (!handle->GetPrivilege().empty())
- b.Add(AUL_K_COM_PRIVILEGE, handle->GetPrivilege());
- }
-
- int ret;
- if (sync) {
- ret = app_send_cmd(AUL_UTIL_PID, APP_COM_CREATE, b.GetHandle());
- } else {
- ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_COM_CREATE,
- b.GetHandle());
- }
-
- if (ret == 0) {
- *connection = static_cast<aul_app_com_connection_h>(
- context.AddConnection(endpoint, callback, user_data));
- }
-
- return ret;
-}
-
extern "C" API int aul_app_com_create(const char* endpoint,
aul_app_com_permission_h permission, app_com_cb callback,
void* user_data, aul_app_com_connection_h* connection) {
return AUL_R_ENOINIT;
}
- tizen_base::Bundle b;
- b.Add(AUL_K_COM_ENDPOINT, endpoint);
+ tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
if (filter)
b.Add(AUL_K_COM_FILTER, filter);
- int ret = app_send_cmd(AUL_UTIL_PID, APP_COM_JOIN, b.GetHandle());
+ int ret = AppRequest(APP_COM_JOIN, getuid())
+ .With(std::move(b))
+ .SendSimply();
if (ret == 0) {
*connection = static_cast<aul_app_com_connection_h>(
context.AddConnection(endpoint, callback, user_data));
if (endpoint == nullptr || envelope == nullptr)
return AUL_R_EINVAL;
- bundle_del(envelope, AUL_K_COM_ENDPOINT);
- bundle_add(envelope, AUL_K_COM_ENDPOINT, endpoint);
- return app_send_cmd(AUL_UTIL_PID, APP_COM_SEND, envelope);
+ std::string com_endpoint;
+ tizen_base::Bundle b(envelope, false, false);
+ bundle_type type = b.GetType(AUL_K_COM_ENDPOINT);
+ if (type != BUNDLE_TYPE_NONE) {
+ com_endpoint = b.GetString(AUL_K_COM_ENDPOINT);
+ b.Delete(AUL_K_COM_ENDPOINT);
+ }
+
+ b.Add(AUL_K_COM_ENDPOINT, endpoint);
+
+ int ret = AppRequest(APP_COM_SEND, getuid())
+ .With(std::move(b))
+ .SendSimply();
+ if (type != BUNDLE_TYPE_NONE) {
+ bundle_del(envelope, AUL_K_COM_ENDPOINT);
+ bundle_add_str(envelope, AUL_K_COM_ENDPOINT, com_endpoint.c_str());
+ }
+
+ return ret;
}
extern "C" API int aul_app_com_leave(aul_app_com_connection_h connection) {
return AUL_R_EINVAL;
}
+ std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
+ conn->Disable();
+
std::string endpoint = conn->GetEndpoint();
- context.RemoveConnection(conn);
+ if (!context.ExistConnection(endpoint)) {
+ tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
+ int ret = AppRequest(APP_COM_LEAVE, getuid())
+ .With(std::move(b))
+ .SendSimply(AUL_SOCK_NOREPLY);
+ if (ret != 0)
+ _E("Failed to send leave request. error(%d)", ret);
+ }
- if (context.ExistConnection(endpoint))
- return AUL_R_OK;
+ g_idle_add_full(G_PRIORITY_HIGH, [](gpointer user_data) -> gboolean {
+ auto* conn = static_cast<AppComConnection*>(user_data);
+ std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
+ context.RemoveConnection(conn);
+ return G_SOURCE_REMOVE;
+ }, connection, nullptr);
- tizen_base::Bundle b;
- b.Add(AUL_K_COM_ENDPOINT, endpoint);
- return app_send_cmd(AUL_UTIL_PID, APP_COM_LEAVE, b.GetHandle());
+ return AUL_R_OK;
}