From: jusung son Date: Wed, 12 Jul 2023 07:42:32 +0000 (+0900) Subject: Support local execution mode X-Git-Tag: accepted/tizen/unified/20230914.164942~31 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=de32a416c3515e68b58fe94e9568f76d89842e4d;p=platform%2Fcore%2Fappfw%2Ftidl.git Support local execution mode Change-Id: I513c91723010011fe6329d786ac3a0ea4e890ae9 Signed-off-by: jusung son --- diff --git a/idlc/gen/c_body_gen_base_cb.h b/idlc/gen/c_body_gen_base_cb.h index 4cb55d61..acfe626f 100644 --- a/idlc/gen/c_body_gen_base_cb.h +++ b/idlc/gen/c_body_gen_base_cb.h @@ -64,6 +64,11 @@ R"__c_cb( #ifndef STRING_GET #define STRING_GET(x) ((x) ? x : "") #endif + +#ifndef EXPORT_API +#define EXPORT_API extern "C" __attribute__ ((visibility("default"))) +#endif + )__c_cb"; /** diff --git a/idlc/gen/version2/c_body_generator_base.cc b/idlc/gen/version2/c_body_generator_base.cc index fe696ece..8c53c312 100644 --- a/idlc/gen/version2/c_body_generator_base.cc +++ b/idlc/gen/version2/c_body_generator_base.cc @@ -30,6 +30,9 @@ namespace tidl { namespace version2 { namespace { +constexpr const char PREFIX_RPC_PORT_PROXY[] = "rpc_port_proxy"; +constexpr const char PREFIX_RPC_PORT_STUB[] = "rpc_port_stub"; + bool IsPtrType(const BaseType& type) { if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE || type.GetUserDefinedType() == BaseType::UserType::DELEGATE || @@ -104,6 +107,14 @@ void CBodyGeneratorBase::AddTypeName(const Structure& st) { struct_types_[std::move(name)] = std::move(type_name); } +void CBodyGeneratorBase::GenIncludeLemHeaders(std::ofstream& stream) { + stream << SmartIndent(CB_LEM_HEADER); +} + +void CBodyGeneratorBase::GenLemBaseDefinition(std::ofstream& stream) { + stream << SmartIndent(CB_LEM_BASE_DEFS); +} + void CBodyGeneratorBase::GenStructureDefinition(std::ofstream& stream) { for (auto& b : GetDocument().GetBlocks()) { if (b->GetType() == Block::TYPE_STRUCTURE) { @@ -131,6 +142,15 @@ bool CBodyGeneratorBase::HasDelegate() { return has_delegate_; } +std::string CBodyGeneratorBase::GetHandlePrefixReverse() { + std::string prefix = + IsProxy() ? PREFIX_RPC_PORT_STUB : PREFIX_RPC_PORT_PROXY; + if (!HasNamespace()) + return prefix; + + return prefix + "_" + GetFileNamespace(); +} + void CBodyGeneratorBase::GenStructureArrayBaseDefinition(std::ofstream& stream, const Structure& st) { auto& elm = *(st.GetElements().begin()); diff --git a/idlc/gen/version2/c_body_generator_base.hh b/idlc/gen/version2/c_body_generator_base.hh index 66172b9c..dfdca332 100644 --- a/idlc/gen/version2/c_body_generator_base.hh +++ b/idlc/gen/version2/c_body_generator_base.hh @@ -37,6 +37,9 @@ class CBodyGeneratorBase : public tidl::CBodyGeneratorBase { void GenUnitMapDefinition(std::ofstream& stream); void GenUnitMapBase(std::ofstream& stream); bool HasDelegate(); + void GenLemBaseDefinition(std::ofstream& stream); + void GenIncludeLemHeaders(std::ofstream& stream); + std::string GetHandlePrefixReverse(); private: void AddTypeName(const Structure& st); diff --git a/idlc/gen/version2/c_body_generator_base_cb.hh b/idlc/gen/version2/c_body_generator_base_cb.hh index 1fc3fffa..95ffe827 100644 --- a/idlc/gen/version2/c_body_generator_base_cb.hh +++ b/idlc/gen/version2/c_body_generator_base_cb.hh @@ -20,6 +20,40 @@ namespace tidl { namespace version2 { +constexpr const char CB_LEM_HEADER[] = +R"__c_cb( +#include +#include +#include +)__c_cb"; + +constexpr const char CB_LEM_BASE_DEFS[] = +R"__c_cb( +typedef struct { + int ret; + rpc_port_unit_map_h lem_ret; +} rpc_port_result_s; + +typedef bool (*rpc_port_stub_is_listen)(); +typedef int(*rpc_port_proxy_LEM_received)(const char *endpoint, const char *port_name, rpc_port_unit_map_h map, void *data); +typedef rpc_port_result_s (*rpc_port_stub_LEM_received_event_cb)(const char *sender, const char *instance, rpc_port_parcel_h parcel, void *user_data); + +typedef struct { + rpc_port_stub_LEM_received_event_cb send; + rpc_port_stub_connected_event_cb connect; + rpc_port_stub_disconnected_event_cb disconnect; + rpc_port_stub_is_listen is_listen; +} rpc_port_stub_LEM_callback_s; + +typedef struct { + rpc_port_proxy_LEM_received send; + rpc_port_proxy_connected_event_cb connect; + rpc_port_proxy_disconnected_event_cb disconnect; + bool is_LEM; + void *user_data; +} rpc_port_proxy_LEM_callback_s; +)__c_cb"; + constexpr const char CB_UNIT_MAP_DEFS[] = R"__c_cb( typedef struct rpc_port_unit_s { diff --git a/idlc/gen/version2/c_proxy_body_generator.cc b/idlc/gen/version2/c_proxy_body_generator.cc index 54380df2..7f4f7fbc 100644 --- a/idlc/gen/version2/c_proxy_body_generator.cc +++ b/idlc/gen/version2/c_proxy_body_generator.cc @@ -33,12 +33,14 @@ void CProxyBodyGenerator::OnInitGen(std::ofstream& stream) { GenVersion(stream); GenGNUSourceDefinition(stream); GenIncludeDefaultHeaders(stream); + GenIncludeLemHeaders(stream); GenIncludeHeader(stream); GenLogTag(stream, std::string("RPC_PORT_PROXY")); GenLogDefinition(stream); GenVersionDefinition(stream); GenBaseDefinition(stream); GenUnitMapDefinition(stream); + GenLemDefinition(stream); GenDelegateDefinition(stream); GenInterfaceDelegateCallback(stream); GenStructureDefinition(stream); @@ -53,6 +55,11 @@ void CProxyBodyGenerator::OnInitGen(std::ofstream& stream) { void CProxyBodyGenerator::OnFiniGen(std::ofstream& stream) { } +void CProxyBodyGenerator::GenLemDefinition(std::ofstream& stream) { + GenLemBaseDefinition(stream); + stream << SmartIndent(CB_LEM_PROXY_BASE_DEF); +} + void CProxyBodyGenerator::GenDelegateDefinition(std::ofstream& stream) { if (HasDelegate()) stream << SmartIndent(CB_DELEGATE_DEFS); @@ -389,11 +396,14 @@ void CProxyBodyGenerator::GenInterfaceBase(std::ofstream& stream, std::string prefix = GetHandlePrefix(); std::string name = iface.GetID(); std::string event = HasDelegate() ? CB_INTERFACE_DELEGATE_REGISTER_EVENT : ""; + std::string callback = HasDelegate() ? CB_INTERFACE_DELEGATE_LEM_RECEIVE_CALLBACK : ""; ReplaceAll(CB_INTERFACE_BASE) .Change("", event) + .Change("", callback) .Change("", prefix) .Change("", name) + .Change("", GetHandlePrefixReverse()) .ChangeToUpper("", prefix) .ChangeToUpper("", name) .Transform([&](std::string code) { return SmartIndent(code); }) diff --git a/idlc/gen/version2/c_proxy_body_generator.hh b/idlc/gen/version2/c_proxy_body_generator.hh index c4bb3472..806ef3e7 100644 --- a/idlc/gen/version2/c_proxy_body_generator.hh +++ b/idlc/gen/version2/c_proxy_body_generator.hh @@ -86,6 +86,7 @@ class CProxyBodyGenerator : public CBodyGeneratorBase { const Interface& iface); void GenDelegateDefinition(std::ofstream& stream); void GenDelegateBase(std::ofstream& stream); + void GenLemDefinition(std::ofstream& stream); private: std::shared_ptr options_; diff --git a/idlc/gen/version2/c_proxy_body_generator_cb.hh b/idlc/gen/version2/c_proxy_body_generator_cb.hh index 9deb02aa..07505ac6 100644 --- a/idlc/gen/version2/c_proxy_body_generator_cb.hh +++ b/idlc/gen/version2/c_proxy_body_generator_cb.hh @@ -19,6 +19,12 @@ namespace tidl { namespace version2 { +constexpr const char CB_LEM_PROXY_BASE_DEF[] = +R"__c_cb( +typedef void (*rpc_port_stub_LEM_init)(rpc_port_stub_LEM_callback_s *cb); +char *__proxy_appid; + +)__c_cb"; constexpr const char CB_DELEGATE_DEFS[] = R"__c_cb( @@ -573,8 +579,14 @@ typedef struct __s { __callback_s callback; void *user_data; GList *delegates; + bool is_LEM; + bool is_LEM_connected; + rpc_port_stub_LEM_callback_s lem_cb; + char *lem_instance_id; GRecMutex mutex; } __t; + +__h ____handle; )__c_cb"; /** @@ -608,6 +620,16 @@ static void ____process_received_event(GList **delegates, rpc_port rpc_port_delegate_destroy(delegate); } +static int ____LEM_received(const char *endpoint, const char *port_name, rpc_port_unit_map_h map, void *data) +{ + __h h = data; + + _W("endpoint(%s), port_name(%s)", endpoint, port_name); + ____process_received_event(&h->delegates, map); + + return RPC_PORT_ERROR_NONE; +} + static void ____received(const char *endpoint, const char *port_name, void *data) { __h h = data; @@ -643,7 +665,6 @@ static void ____received(const char *endpoint, const char *port_na ____process_received_event(&h->delegates, map); rpc_port_unit_map_destroy(map); } - )__c_cb"; /** @@ -660,6 +681,15 @@ if (ret != RPC_PORT_ERROR_NONE) { } )__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + */ +constexpr const char CB_INTERFACE_DELEGATE_LEM_RECEIVE_CALLBACK[] = +R"__c_cb(cb->send = ____LEM_received; +)__c_cb"; + /** * The prefix of the interface. * The name of the interface. @@ -725,8 +755,12 @@ static void ____connected(const char *endpoint, const char *port_n __h h = data; _I("endpoint(%s), port_name(%s)", endpoint, port_name); - h->port = port; - rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port); + if(h->is_LEM) { + h->is_LEM_connected = true; + } else { + h->port = port; + rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port); + } h->callback.connected(h, h->user_data); } @@ -735,6 +769,7 @@ static void ____disconnected(const char *endpoint, const char *por __h h = data; _W("endpoint(%s), port_name(%s)", endpoint, port_name); + h->is_LEM_connected = false; h->port = nullptr; h->callback.disconnected(h, h->user_data); } @@ -748,10 +783,24 @@ static void ____rejected(const char *endpoint, const char *port_na h->callback.rejected(h, h->user_data); } +static gboolean ____LEM_connected(gpointer user_data) { + ____connected(__proxy_appid, "", nullptr, user_data); + return FALSE; +} + +EXPORT_API void __LEM_init(rpc_port_proxy_LEM_callback_s *cb) { + cb->connect = ____connected; + cb->disconnect = ____disconnected; + cb->is_LEM = ____handle->is_LEM; + cb->user_data = ____handle; + +} + int __create(const char *stub_appid, __callback_s *callback, void *user_data, __h *h) { __t *handle; int ret; + rpc_port_stub_LEM_init lem_init; if (stub_appid == nullptr || callback == nullptr || h == nullptr) { _E("Invalid parameter"); @@ -811,6 +860,18 @@ int __create(const char *stub_appid, __callback_s *c *h = handle; + ____handle = handle; + + void *plugin_handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); + if (plugin_handle == NULL) + return RPC_PORT_ERROR_NONE; + + lem_init = dlsym(plugin_handle, "__LEM_init"); + if (lem_init == NULL) + return RPC_PORT_ERROR_NONE; + + lem_init(&handle->lem_cb); + return RPC_PORT_ERROR_NONE; } @@ -834,6 +895,12 @@ int __destroy(__h h) if (h->stub_appid) free(h->stub_appid); + if (h->is_LEM && h->is_LEM_connected) { + _I("LEM destroy (%s)", __proxy_appid); + h->is_LEM_connected = false; + h->lem_cb.disconnect(__proxy_appid, h->lem_instance_id, nullptr); + } + free(h); return RPC_PORT_ERROR_NONE; @@ -841,14 +908,37 @@ int __destroy(__h h) int __connect(__h h) { - int ret; + int ret = RPC_PORT_ERROR_NONE; + char instance_id[512]; if (h == nullptr || h->proxy == nullptr) { _E("Invalid parameter"); return RPC_PORT_ERROR_INVALID_PARAMETER; } - ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, ""); + if (__proxy_appid == nullptr) + app_get_id(&__proxy_appid); + + if (__proxy_appid != nullptr && !strcmp(__proxy_appid, h->stub_appid)) { + if (h->lem_cb.is_listen != nullptr) + h->is_LEM = h->lem_cb.is_listen(); + + _I("LEM appid (%s) (%d)", __proxy_appid, h->is_LEM); + } + + if (h->is_LEM) { + snprintf(instance_id, sizeof(instance_id), "LEM_@%s", __proxy_appid); + + h->lem_instance_id = strdup(instance_id); + h->lem_cb.connect(__proxy_appid, h->lem_instance_id ? h->lem_instance_id : "LEM_", &ret); + + if (ret == RPC_PORT_ERROR_NONE) + g_idle_add(____LEM_connected, h); + + } else { + ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, ""); + } + if (ret != RPC_PORT_ERROR_NONE) { _E("Failed to connect to stub. error(%d)", ret); return ret; @@ -859,14 +949,33 @@ int __connect(__h h) int __connect_sync(__h h) { - int ret; + int ret = RPC_PORT_ERROR_NONE; + char instance_id[512]; if (h == nullptr || h->proxy == nullptr) { _E("Invalid parameter"); return RPC_PORT_ERROR_INVALID_PARAMETER; } - ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, ""); + if (__proxy_appid == nullptr) + app_get_id(&__proxy_appid); + + if (__proxy_appid != nullptr && !strcmp(__proxy_appid, h->stub_appid)) { + if (h->lem_cb.is_listen != nullptr) + h->is_LEM = h->lem_cb.is_listen(); + + _I("LEM appid (%s) (%d)", __proxy_appid, h->is_LEM); + } + + if (h->is_LEM) { + snprintf(instance_id, sizeof(instance_id), "LEM_@%s", __proxy_appid); + + h->lem_instance_id = strdup(instance_id); + h->lem_cb.connect(__proxy_appid, h->lem_instance_id ? h->lem_instance_id : "LEM_", &ret); + } else { + ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, ""); + } + if (ret != RPC_PORT_ERROR_NONE) { _E("Failed to connect to stub. error(%d)", ret); return ret; @@ -879,15 +988,26 @@ int __disconnect(__h h) { int ret; - if (h == nullptr || h->proxy == nullptr) { + if (h == nullptr ) { _E("Invalid parameter"); return RPC_PORT_ERROR_INVALID_PARAMETER; } - ret = rpc_port_disconnect(h->port); - if (ret != RPC_PORT_ERROR_NONE) { - _E("Failed to disconnect from stub. error(%d)", ret); - return ret; + if (h->proxy == nullptr && h->is_LEM_connected == false) { + _E("Invalid parameter"); + return RPC_PORT_ERROR_INVALID_PARAMETER; + } + + if (h->is_LEM) { + _I("LEM disconnect (%s)", __proxy_appid); + h->is_LEM_connected = false; + h->lem_cb.disconnect(__proxy_appid, h->lem_instance_id, nullptr); + } else { + ret = rpc_port_disconnect(h->port); + if (ret != RPC_PORT_ERROR_NONE) { + _E("Failed to disconnect from stub. error(%d)", ret); + return ret; + } } return RPC_PORT_ERROR_NONE; @@ -915,6 +1035,7 @@ void __invoke_(__h h) rpc_port_unit_map_h map_; int seq_num_ = -1; int res_; + rpc_port_result_s stub_result; if (h == nullptr) { _E("Invalid parameter"); @@ -922,7 +1043,7 @@ void __invoke_(__h h) return; } - if (h->port == nullptr) { + if (h->port == nullptr && h->is_LEM_connected == false) { _E("Not connected"); set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER); return; @@ -956,7 +1077,13 @@ void __invoke_(__h h) rpc_port_unit_map_destroy(map_); g_rec_mutex_lock(&h->mutex); - res_ = rpc_port_parcel_send(parcel_, h->port); + if (h->is_LEM_connected) { + stub_result = h->lem_cb.send(__proxy_appid, h->lem_instance_id, parcel_, nullptr); + res_ = stub_result.ret; + } else { + res_ = rpc_port_parcel_send(parcel_, h->port); + } + rpc_port_parcel_destroy(parcel_); if (res_ != RPC_PORT_ERROR_NONE) _E("Failed to send parcel. error(%d)", res_); @@ -991,6 +1118,7 @@ R"__c_cb( rpc_port_unit_map_h map_; int seq_num_ = -1; int res_; + rpc_port_result_s stub_result; ret_ = ; @@ -1000,7 +1128,7 @@ R"__c_cb( return ret_; } - if (h->port == nullptr) { + if (h->port == nullptr && h->is_LEM_connected == false) { _E("Not connected"); set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER); return ret_; @@ -1035,7 +1163,12 @@ R"__c_cb( g_rec_mutex_lock(&h->mutex); - res_ = rpc_port_parcel_send(parcel_, h->port); + if (h->is_LEM_connected) { + stub_result = h->lem_cb.send(__proxy_appid, h->lem_instance_id, parcel_, nullptr); + res_ = stub_result.ret; + } else { + res_ = rpc_port_parcel_send(parcel_, h->port); + } rpc_port_parcel_destroy(parcel_); if (res_ != RPC_PORT_ERROR_NONE) { _E("Failed to send parcel. error(%d)", res_); @@ -1046,8 +1179,12 @@ R"__c_cb( do { map_ = nullptr; - ____consume_command(h->port, seq_num_, &map_); - if (parcel_ == nullptr) { + if (h->is_LEM_connected) { + map_ = stub_result.lem_ret; + } else { + ____consume_command(h->port, seq_num_, &map_); + } + if (map_ == nullptr) { _E("Invalid protocol"); res_ = RPC_PORT_ERROR_IO_ERROR; break; diff --git a/idlc/gen/version2/c_stub_body_generator.cc b/idlc/gen/version2/c_stub_body_generator.cc index 828f2985..d8c9e5ae 100644 --- a/idlc/gen/version2/c_stub_body_generator.cc +++ b/idlc/gen/version2/c_stub_body_generator.cc @@ -32,6 +32,7 @@ void CStubBodyGenerator::OnInitGen(std::ofstream& stream) { GenGNUSourceDefinition(stream); GenIncludeDefaultHeaders(stream); GenIncludePrivateHeaders(stream); + GenIncludeLemHeaders(stream); GenIncludeHeader(stream); GenLogTag(stream, std::string("RPC_PORT_STUB")); GenLogDefinition(stream); @@ -40,6 +41,7 @@ void CStubBodyGenerator::OnInitGen(std::ofstream& stream) { GenThreadEnableDefinition(stream); GenInterfaceEnums(stream); GenUnitMapDefinition(stream); + GenLemDefinition(stream); GenInterfaceMethodHandlerType(stream); GenDelegateDefinition(stream); GenStructureDefinition(stream); @@ -54,6 +56,11 @@ void CStubBodyGenerator::OnInitGen(std::ofstream& stream) { void CStubBodyGenerator::OnFiniGen(std::ofstream& stream) { } +void CStubBodyGenerator::GenLemDefinition(std::ofstream& stream) { + GenLemBaseDefinition(stream); + stream << SmartIndent(CB_LEM_STUB_BASE_DEF); +} + void CStubBodyGenerator::GenIncludePrivateHeaders(std::ofstream& stream) { stream << CB_PRIVATE_HEADERS; } @@ -816,6 +823,7 @@ void CStubBodyGenerator::GenInterfaceBase(std::ofstream& stream, const Interface& iface) { std::string code(ReplaceAll(CB_INTERFACE_BASE, { { "", GetHandlePrefix() }, + { "", GetHandlePrefixReverse() }, { "", iface.GetID() }, { "", GenAccessControlSet(iface) } })); diff --git a/idlc/gen/version2/c_stub_body_generator.hh b/idlc/gen/version2/c_stub_body_generator.hh index 39439d67..91bd231f 100644 --- a/idlc/gen/version2/c_stub_body_generator.hh +++ b/idlc/gen/version2/c_stub_body_generator.hh @@ -104,6 +104,7 @@ class CStubBodyGenerator : public CBodyGeneratorBase { std::string GenAccessControlSet(const Interface& iface); void GenDelegateDefinition(std::ofstream& stream); void GenDelegateBase(std::ofstream& stream); + void GenLemDefinition(std::ofstream& stream); private: std::shared_ptr options_; diff --git a/idlc/gen/version2/c_stub_body_generator_cb.hh b/idlc/gen/version2/c_stub_body_generator_cb.hh index c94dfc32..9d6c1998 100644 --- a/idlc/gen/version2/c_stub_body_generator_cb.hh +++ b/idlc/gen/version2/c_stub_body_generator_cb.hh @@ -23,6 +23,14 @@ R"__c_cb( #include )__c_cb"; + +constexpr const char CB_LEM_STUB_BASE_DEF[] = +R"__c_cb( +typedef void (*rpc_port_proxy_LEM_init)(rpc_port_proxy_LEM_callback_s *cb); +char *__stub_appid; + +)__c_cb"; + constexpr const char CB_DELEGATE_DEFS[] = R"__c_cb( typedef struct rpc_port_delegate_s { @@ -103,7 +111,7 @@ R"__c_cb( constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] = R"__c_cb( -typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data); +typedef rpc_port_result_s (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data); )__c_cb"; /** @@ -185,6 +193,7 @@ typedef struct __context_s { void *user_data; app_info_h app_info; GHashTable *privileges; + rpc_port_proxy_LEM_callback_s lem_cb; #ifdef TIDL_THREAD_ENABLE GThread *thread; GQueue *queue; @@ -203,6 +212,7 @@ typedef int (*__privilege_checker)(__context_h h, bo constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK_DEF[] = R"__c_cb( static bool ____exist_callback_port(rpc_port_h callback_port); +static __context_h ____find_context(const char *instance); )__c_cb"; /** @@ -219,6 +229,7 @@ typedef struct ___s { int seq_id; bool once; bool valid; + char *lem_instance; } ___t; )__c_cb"; @@ -275,17 +286,18 @@ static void ____throw_remote_exception(rpc_port_h port, rpc_port_p rpc_port_parcel_destroy(result_parcel); } -static int ____context_handle_request(__context_h h, rpc_port_parcel_h parcel) +static rpc_port_result_s ____context_handle_request(__context_h h, rpc_port_parcel_h parcel) { - int ret = RPC_PORT_ERROR_NONE; int cmd = -1; rpc_port_unit_map_h map; bool sync = false; + rpc_port_result_s stub_result = { 0, }; map = rpc_port_unit_map_create(); if (map == nullptr) { _E("Failed to create unit map"); - return RPC_PORT_ERROR_OUT_OF_MEMORY; + stub_result.ret = RPC_PORT_ERROR_OUT_OF_MEMORY; + return stub_result; } rpc_port_parcel_read(parcel, &map->parcelable, map); @@ -293,26 +305,27 @@ static int ____context_handle_request(__context_h h, rpc_port_unit_map_read_int(map, "[METHOD]", &cmd); if (cmd > 1 && cmd < ARRAY_SIZE(___method_table)) { - if (h->app_info && ___privilege_checkers[cmd]) { - ret = ___privilege_checkers[cmd](h, &sync); - if (ret != RPC_PORT_ERROR_NONE) { + if (h->lem_cb.is_LEM == false && h->app_info && ___privilege_checkers[cmd]) { + stub_result.ret = ___privilege_checkers[cmd](h, &sync); + if (stub_result.ret != RPC_PORT_ERROR_NONE) { rpc_port_unit_map_destroy(map); if (sync) - ____throw_remote_exception(h->port, parcel, ret, "Permission denied"); + ____throw_remote_exception(h->port, parcel, stub_result.ret, "Permission denied"); - return RPC_PORT_ERROR_NONE; + stub_result.ret = RPC_PORT_ERROR_NONE; + return stub_result; } } if (___method_table[cmd]) - ret = ___method_table[cmd](h->port, parcel, map, h); + stub_result = ___method_table[cmd](h->port, parcel, map, h); } else { _W("Invalid protocol. cmd(%d)", cmd); - ret = RPC_PORT_ERROR_INVALID_PARAMETER; + stub_result.ret = RPC_PORT_ERROR_INVALID_PARAMETER; } rpc_port_unit_map_destroy(map); - return ret; + return stub_result; } #ifdef TIDL_THREAD_ENABLE @@ -462,11 +475,16 @@ static int ____context_load_privileges(__context_h h return ret; } -static __context_h ____context_create(const char *sender, const char *instance, rpc_port_h callback_port) +static __context_h ____context_create(const char *sender, const char *instance, rpc_port_h callback_port, rpc_port_proxy_LEM_callback_s *lem_cb) { __context_t *handle; - if (sender == nullptr || instance == nullptr || callback_port == nullptr) { + if (sender == nullptr || instance == nullptr) { + _E("Invalid parameter"); + return nullptr; + } + + if (lem_cb->is_LEM == false && callback_port == nullptr) { _E("Invalid parameter"); return nullptr; } @@ -522,6 +540,7 @@ static __context_h ____context_create(const char *se } #endif /* TIDL_THREAD_ENABLE */ + handle->lem_cb = *lem_cb; handle->callback_port = callback_port; handle->callback = __.callback; handle->user_data = __.user_data; @@ -529,6 +548,53 @@ static __context_h ____context_create(const char *se return handle; } +static __context_h ____find_context(const char *instance) +{ + __context_h context; + GList *iter; + + g_rec_mutex_lock(&__.mutex); + iter = __.contexts; + while (iter) { + context = iter->data; + if (!strcmp(context->instance, instance)) { + g_rec_mutex_unlock(&__.mutex); + return context; + } + + iter = g_list_next(iter); + } + g_rec_mutex_unlock(&__.mutex); + + return nullptr; +} + +static void ____add_context(__context_h context) +{ + g_rec_mutex_lock(&__.mutex); + __.contexts = g_list_append(__.contexts, context); + g_rec_mutex_unlock(&__.mutex); +} + +static void ____remove_context(__context_h context) +{ + g_rec_mutex_lock(&__.mutex); + __.contexts = g_list_remove(__.contexts, context); + g_rec_mutex_unlock(&__.mutex); +} + +static void ____clear_context(gpointer data) +{ + __context_h context = data; + + if (context->lem_cb.is_LEM) { + _I("LEM disconnect %s:", __stub_appid); + context->lem_cb.disconnect(__stub_appid, "", context->lem_cb.user_data); + ____remove_context(context); + } + ____context_destroy(context); +} + int __context_set_tag(__context_h context, void *tag) { if (context == nullptr) { @@ -595,7 +661,7 @@ int __context_get_instance(__context_h context, char int __context_disconnect(__context_h context) { - int ret; + int ret = RPC_PORT_ERROR_NONE; if (context == nullptr) { _E("Invalid parameter"); @@ -604,49 +670,21 @@ int __context_disconnect(__context_h context) g_rec_mutex_lock(&__.mutex); - ret = rpc_port_disconnect(context->callback_port); - if (ret != RPC_PORT_ERROR_NONE) - _E("Failed to disconnect. error(%d)", ret); - - g_rec_mutex_unlock(&__.mutex); - - return ret; -} - -static __context_h ____find_context(const char *instance) -{ - __context_h context; - GList *iter; - - g_rec_mutex_lock(&__.mutex); - iter = __.contexts; - while (iter) { - context = iter->data; - if (!strcmp(context->instance, instance)) { - g_rec_mutex_unlock(&__.mutex); - return context; - } - - iter = g_list_next(iter); + if (context->lem_cb.is_LEM) { + _I("LEM disconnect %s:", __stub_appid); + context->lem_cb.disconnect(__stub_appid, "", context->lem_cb.user_data); + ____remove_context(context); + ____context_destroy(context); + } else { + ret = rpc_port_disconnect(context->callback_port); + if (ret != RPC_PORT_ERROR_NONE) + _E("Failed to disconnect. error(%d)", ret); } g_rec_mutex_unlock(&__.mutex); - return nullptr; -} - -static void ____add_context(__context_h context) -{ - g_rec_mutex_lock(&__.mutex); - __.contexts = g_list_append(__.contexts, context); - g_rec_mutex_unlock(&__.mutex); + return ret; } -static void ____remove_context(__context_h context) -{ - g_rec_mutex_lock(&__.mutex); - __.contexts = g_list_remove(__.contexts, context); - g_rec_mutex_unlock(&__.mutex); -} )__c_cb"; /** @@ -773,6 +811,9 @@ int ___destroy(___h h) _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false"); + if (h->lem_instance) + free(h->lem_instance); + free(h); return RPC_PORT_ERROR_NONE; @@ -806,6 +847,15 @@ int ___clone(___h h, < (*clone)->port = h->port; + if (h->lem_instance) { + (*clone)->lem_instance = strdup(h->lem_instance); + if ((*clone)->lem_instance == nullptr) { + _E("Out of memory"); + ___destroy(*clone); + return RPC_PORT_ERROR_OUT_OF_MEMORY; + } + } + return ret; } @@ -884,15 +934,28 @@ int ___invoke(___h h__context_h context = nullptr; - if (h == nullptr || h->port == nullptr) { + if (h == nullptr ) { _E("Invalid parameter"); return RPC_PORT_ERROR_INVALID_PARAMETER; } - if (!____exist_callback_port(h->port)) { - _E("Not connected"); - return RPC_PORT_ERROR_INVALID_PARAMETER; + if (h->lem_instance) { + context = ____find_context(h->lem_instance); + if (context == nullptr) { + _E("Not connected"); + return RPC_PORT_ERROR_INVALID_PARAMETER; + } + } else { + if (h->port == nullptr) { + _E("Invalid parameter"); + return RPC_PORT_ERROR_INVALID_PARAMETER; + } + if (!____exist_callback_port(h->port)) { + _E("Not connected"); + return RPC_PORT_ERROR_INVALID_PARAMETER; + } } if (h->once && !h->valid) { @@ -919,10 +982,14 @@ int ___invoke(___h h - rpc_port_parcel_write(parcel_, &map_->parcelable, map_); + if (context && context->lem_cb.is_LEM) { + ret_ = context->lem_cb.send("endpoint", "Message", map_, context->lem_cb.user_data); + } else { + rpc_port_parcel_write(parcel_, &map_->parcelable, map_); + ret_ = rpc_port_parcel_send(parcel_, h->port); + } rpc_port_unit_map_destroy(map_); - ret_ = rpc_port_parcel_send(parcel_, h->port); rpc_port_parcel_destroy(parcel_); h->valid = false; @@ -1047,8 +1114,17 @@ if (ret_ != RPC_PORT_ERROR_NONE) { _E("Failed to read delegate. error(%d)", ret_); goto out; } -__set_port(, callback_port_); +if (context_->lem_cb.is_LEM) { + ->lem_instance = strdup(context_->instance); + if (->lem_instance == nullptr) { + _E("Failed to duplicate sender"); + ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY; + goto out; + } +} else { + __set_port(, callback_port_); +} )__c_cb"; @@ -1079,20 +1155,23 @@ if (ret_ != RPC_PORT_ERROR_NONE) { */ constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] = R"__c_cb( -static int ____method__handler(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *user_data) +static rpc_port_result_s ____method__handler(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *user_data) { __context_h context_ = user_data; rpc_port_parcel_header_h header_; int seq_num_ = -1; rpc_port_h callback_port_; - int ret_; + int ret_ = RPC_PORT_ERROR_NONE; + rpc_port_result_s stub_result_ = { 0, }; - ret_ = rpc_port_stub_get_port(__.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_); - if (ret_ != RPC_PORT_ERROR_NONE) { - _E("Failed to get callback port. error(%d)", ret_); - goto out; + if (context_->lem_cb.is_LEM == false) { + ret_ = rpc_port_stub_get_port(__.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_); + if (ret_ != RPC_PORT_ERROR_NONE) { + _E("Failed to get callback port. error(%d)", ret_); + goto out; + } } rpc_port_parcel_get_header(parcel, &header_); @@ -1105,7 +1184,8 @@ static int ____method__handler(rpc_port_h port, rpc_p out: - return ret_; + stub_result_.ret = ret_; + return stub_result_; } )__c_cb"; @@ -1241,11 +1321,15 @@ R"__c_cb( if (____remote_exception != nullptr) rpc_port_unit_map_write__remote_exception(map_, "[REMOTE_EXCEPTION]", ____remote_exception); -rpc_port_parcel_write(parcel_, &map_->parcelable, map_); -rpc_port_unit_map_destroy(map_); + if (context_->lem_cb.is_LEM) { + stub_result_.lem_ret = map_; +} else { + rpc_port_parcel_write(parcel_, &map_->parcelable, map_); + rpc_port_unit_map_destroy(map_); -ret_ = rpc_port_parcel_send(parcel_, port); -rpc_port_parcel_destroy(parcel_); + ret_ = rpc_port_parcel_send(parcel_, port); + rpc_port_parcel_destroy(parcel_); +} )__c_cb"; @@ -1326,21 +1410,47 @@ static void ____connected_event_cb(const char *sender, const char __context_h context; rpc_port_h callback_port = nullptr; int ret; - + rpc_port_proxy_LEM_callback_s lem_cb = { 0, }; + rpc_port_proxy_LEM_init lem_init; + + if (__stub_appid == nullptr) + app_get_id(&__stub_appid); + + if (__stub_appid != nullptr) { + if (!strcmp(__stub_appid, sender)) { + void *plugin_handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); + if (plugin_handle) { + lem_init = dlsym(plugin_handle, "__LEM_init"); + if (lem_init) + lem_init(&lem_cb); + } + } + } _W("sender(%s), instance(%s)", sender, instance); - ret = rpc_port_stub_get_port(__.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port); - if (ret != RPC_PORT_ERROR_NONE) { - _E("Failed to get callback port. error(%d)", ret); - return; + if (lem_cb.is_LEM == false) { + ret = rpc_port_stub_get_port(__.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port); + if (ret != RPC_PORT_ERROR_NONE) { + _E("Failed to get callback port. error(%d)", ret); + return; + } } - context = ____context_create(sender, instance, callback_port); - if (context == nullptr) + context = ____context_create(sender, instance, callback_port, &lem_cb); + if (context == nullptr) { + if (lem_cb.is_LEM) + *((int *)user_data) = RPC_PORT_ERROR_IO_ERROR; return; + } ____add_context(context); - ____add_callback_port(context->callback_port); + + if (lem_cb.is_LEM == false) + ____add_callback_port(context->callback_port); + context->callback.create(context, context->user_data); + + if (lem_cb.is_LEM) + *((int *)user_data) = RPC_PORT_ERROR_NONE; } static void ____disconnected_event_cb(const char *sender, const char *instance, void *user_data) @@ -1353,7 +1463,9 @@ static void ____disconnected_event_cb(const char *sender, const ch if (context == nullptr) return; - ____remove_callback_port(context->callback_port); + if (context->lem_cb.is_LEM == false) + ____remove_callback_port(context->callback_port); + context->callback.terminate(context, context->user_data); ____remove_context(context); ____context_destroy(context); @@ -1364,6 +1476,7 @@ static int ____received_event_cb(const char *sender, const char *i __context_h context; rpc_port_parcel_h parcel; int ret; + rpc_port_result_s stub_result = { 0, }; _W("sender(%s), instance(%s)", sender, instance); context = ____find_context(instance); @@ -1380,13 +1493,42 @@ static int ____received_event_cb(const char *sender, const char *i } #ifdef TIDL_THREAD_ENABLE - ret = ____context_push(context, parcel); + stub_result.ret = ____context_push(context, parcel); #else - ret = ____context_handle_request(context, parcel); + stub_result = ____context_handle_request(context, parcel); rpc_port_parcel_destroy(parcel); #endif /* TIDL_THREAD_ENABLE */ - return ret; + return stub_result.ret; +} + +rpc_port_result_s ____LEM_received_event_cb(const char *sender, const char *instance, rpc_port_parcel_h parcel, void *user_data) +{ + __context_h context; + rpc_port_result_s stub_result = { 0, }; + + _W("sender(%s), instance(%s)", sender, instance); + context = ____find_context(instance); + if (context == nullptr) { + _E("Failed to find context. instance(%s)", instance); + stub_result.ret = RPC_PORT_ERROR_INVALID_PARAMETER; + return stub_result; + } + + stub_result = ____context_handle_request(context, parcel); + + return stub_result; +} + +static bool ____received_event_cb_is_listen() { + return __.stub != NULL; +} + +EXPORT_API void __LEM_init(rpc_port_stub_LEM_callback_s *cb) { + cb->connect = ____connected_event_cb; + cb->disconnect = ____disconnected_event_cb; + cb->send = ____LEM_received_event_cb; + cb->is_listen = ____received_event_cb_is_listen; } static int ____set_access_control(void) @@ -1471,7 +1613,7 @@ int __unregister(void) g_rec_mutex_clear(&__.mutex); if (__.contexts) { - g_list_free_full(__.contexts, ____context_destroy); + g_list_free_full(__.contexts, ____clear_context); __.contexts = nullptr; } diff --git a/tests/build_tests/CMakeLists.txt b/tests/build_tests/CMakeLists.txt index dc629f9d..85689a5e 100644 --- a/tests/build_tests/CMakeLists.txt +++ b/tests/build_tests/CMakeLists.txt @@ -120,6 +120,6 @@ ADD_EXECUTABLE(${TARGET_TIDL_BUILD_TESTS} ${TIDL_GEN_SRCS} ) -TARGET_LINK_LIBRARIES(${TARGET_TIDL_BUILD_TESTS} ${PKGS_LDFLAGS} "-lpthread") +TARGET_LINK_LIBRARIES(${TARGET_TIDL_BUILD_TESTS} ${PKGS_LDFLAGS} "-ldl -lpthread") INSTALL(TARGETS ${TARGET_TIDL_BUILD_TESTS} DESTINATION bin)