From 39688225755e4f185f9d1abf13ef45b8853c899b Mon Sep 17 00:00:00 2001 From: zgit2021 Date: Wed, 22 Dec 2021 16:26:42 +0800 Subject: [PATCH] OHOS_1230 sync code Signed-off-by: zgit2021 Change-Id: I52c10834947bfe703943904e0ae93a7a7560a5e5 --- interfaces/innerkits/ipc_core/BUILD.gn | 1 + .../ipc_core/include/ipc_object_proxy.h | 1 + .../ipc_core/include/ipc_object_stub.h | 7 +- .../innerkits/ipc_core/include/ipc_types.h | 9 ++ .../ipc_core/include/message_parcel.h | 3 + .../libdbinder/include/dbinder_service_stub.h | 4 - .../src/core/include/dbinder_callback_stub.h | 43 ++++++ .../src/core/include/ipc_process_skeleton.h | 8 + .../src/core/source/dbinder_callback_stub.cpp | 141 ++++++++++++++++++ .../src/core/source/ipc_object_proxy.cpp | 27 ++++ .../src/core/source/ipc_object_stub.cpp | 54 ++++++- .../src/core/source/ipc_process_skeleton.cpp | 48 +++++- ipc/native/src/core/source/message_parcel.cpp | 89 ++++++++++- ipc/native/src/mock/include/sys_binder.h | 9 -- ipc/native/src/napi/src/napi_ashmem.cpp | 12 ++ ipc/native/test/unittest/common/BUILD.gn | 4 +- ipc/test/auxiliary/native/BUILD.gn | 10 +- ipc/test/moduletest/native/BUILD.gn | 2 +- ohos.build | 10 -- services/dbinder/test/BUILD.gn | 2 +- .../include/dbinder_test_service.h | 2 + .../include/dbinder_test_service_skeleton.h | 7 + .../src/dbinder_distributed_test.cpp | 39 +++++ .../src/dbinder_test_service.cpp | 7 + .../src/dbinder_test_service_skeleton.cpp | 83 ++++++++++- 25 files changed, 574 insertions(+), 48 deletions(-) create mode 100644 ipc/native/src/core/include/dbinder_callback_stub.h create mode 100644 ipc/native/src/core/source/dbinder_callback_stub.cpp diff --git a/interfaces/innerkits/ipc_core/BUILD.gn b/interfaces/innerkits/ipc_core/BUILD.gn index 370a6ab..33a23af 100755 --- a/interfaces/innerkits/ipc_core/BUILD.gn +++ b/interfaces/innerkits/ipc_core/BUILD.gn @@ -28,6 +28,7 @@ ohos_shared_library("ipc_core") { "$IPC_CORE_ROOT/src/core/source/buffer_object.cpp", "$IPC_CORE_ROOT/src/core/source/comm_auth_info.cpp", "$IPC_CORE_ROOT/src/core/source/databus_session_callback.cpp", + "$IPC_CORE_ROOT/src/core/source/dbinder_callback_stub.cpp", "$IPC_CORE_ROOT/src/core/source/dbinder_session_object.cpp", "$IPC_CORE_ROOT/src/core/source/ipc_file_descriptor.cpp", "$IPC_CORE_ROOT/src/core/source/ipc_object_proxy.cpp", diff --git a/interfaces/innerkits/ipc_core/include/ipc_object_proxy.h b/interfaces/innerkits/ipc_core/include/ipc_object_proxy.h index 1d66e4b..67d0a97 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_object_proxy.h +++ b/interfaces/innerkits/ipc_core/include/ipc_object_proxy.h @@ -69,6 +69,7 @@ public: std::string GetPidAndUidInfo(); std::string GetDataBusName(); + std::string TransDataBusName(uint32_t uid, uint32_t pid); int GetProto() const; void WaitForInit(); std::u16string GetInterfaceDescriptor(); diff --git a/interfaces/innerkits/ipc_core/include/ipc_object_stub.h b/interfaces/innerkits/ipc_core/include/ipc_object_stub.h index f4fe929..71d78e3 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_object_stub.h +++ b/interfaces/innerkits/ipc_core/include/ipc_object_stub.h @@ -70,18 +70,15 @@ public: #ifndef CONFIG_IPC_SINGLE int32_t InvokerThread(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t NoticeServiceDie(MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t InvokerDataBusThread(MessageParcel &data, MessageParcel &reply); - int32_t IncStubRefs(MessageParcel &data, MessageParcel &reply); int32_t DecStubRefs(MessageParcel &data, MessageParcel &reply); - - int32_t AddAuthInfo(MessageParcel &data, MessageParcel &reply); + int32_t AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code); private: int32_t GrantDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t TransDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); std::string CreateDatabusName(int uid, int pid); std::string GetDataBusName(); #endif diff --git a/interfaces/innerkits/ipc_core/include/ipc_types.h b/interfaces/innerkits/ipc_core/include/ipc_types.h index df3b3cb..2257c0c 100755 --- a/interfaces/innerkits/ipc_core/include/ipc_types.h +++ b/interfaces/innerkits/ipc_core/include/ipc_types.h @@ -38,10 +38,12 @@ enum { GET_PROTO_INFO = ZIPC_PACK_CHARS('_', 'G', 'R', 'I'), GET_UIDPID_INFO = ZIPC_PACK_CHARS('_', 'G', 'U', 'I'), GRANT_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'G', 'D', 'N'), + TRANS_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'T', 'D', 'N'), DBINDER_OBITUARY_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'O', 'T'), DBINDER_INCREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'I', 'T'), DBINDER_DECREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'D', 'T'), DBINDER_ADD_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'A', 'C'), + DBINDER_TRANS_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'T', 'C'), TRANS_SYNC = 0, TRANS_ASYNC = 1, }; @@ -117,6 +119,13 @@ enum { SESSION_INVOKER_NULL_ERR, SESSION_UNAUTHENTICATED_ERR, SESSION_UNOPEN_ERR = -1, + DBINDER_CALLBACK_ERR = 900, + DBINDER_CALLBACK_ADD_DEATH_ERR, + DBINDER_CALLBACK_RMV_DEATH_ERR, + DBINDER_CALLBACK_READ_OBJECT_ERR, + BINDER_CALLBACK_AUTHCOMM_ERR, + BINDER_CALLBACK_STUBINDEX_ERR + }; } // namespace OHOS #endif // OHOS_IPC_IPC_TYPES_H diff --git a/interfaces/innerkits/ipc_core/include/message_parcel.h b/interfaces/innerkits/ipc_core/include/message_parcel.h index 8542b86..af5bfb8 100755 --- a/interfaces/innerkits/ipc_core/include/message_parcel.h +++ b/interfaces/innerkits/ipc_core/include/message_parcel.h @@ -52,6 +52,9 @@ public: }; private: +#ifndef CONFIG_IPC_SINGLE + bool WriteDBinderProxy(const sptr &object, uint32_t handle, uint64_t stubIndex); +#endif static constexpr size_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // 128M static constexpr size_t MIN_RAWDATA_SIZE = 32 * 1024; // 32k bool needCloseFd_ = false; diff --git a/interfaces/innerkits/libdbinder/include/dbinder_service_stub.h b/interfaces/innerkits/libdbinder/include/dbinder_service_stub.h index e6f4f17..93c8f12 100755 --- a/interfaces/innerkits/libdbinder/include/dbinder_service_stub.h +++ b/interfaces/innerkits/libdbinder/include/dbinder_service_stub.h @@ -21,11 +21,7 @@ #include "ipc_object_stub.h" namespace OHOS { -#ifdef BINDER_IPC_32BIT -typedef unsigned int binder_uintptr_t; -#else typedef unsigned long long binder_uintptr_t; -#endif class DBinderServiceStub : public IPCObjectStub { public: diff --git a/ipc/native/src/core/include/dbinder_callback_stub.h b/ipc/native/src/core/include/dbinder_callback_stub.h new file mode 100644 index 0000000..3b0409d --- /dev/null +++ b/ipc/native/src/core/include/dbinder_callback_stub.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IPC_DBINDER_CALLBACK_STUB_H +#define OHOS_IPC_DBINDER_CALLBACK_STUB_H + +#include +#include "ipc_object_stub.h" + +namespace OHOS { +class DBinderCallbackStub : public IPCObjectStub { +public: + explicit DBinderCallbackStub(const std::string &serviceName, const std::string &peerDeviceID, + const std::string &localDeviceID, uint64_t stubIndex, uint32_t handle); + ~DBinderCallbackStub(); + int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + const std::string &GetServiceName(); + const std::string &GetDeviceID(); + uint64_t GetStubIndex() const; + +private: + const std::string serviceName_; + const std::string deviceID_; + const std::string localDeviceID_; + uint64_t stubIndex_; + uint32_t handle_; +}; +} // namespace OHOS +#endif // OHOS_IPC_DBINDER_CALLBACK_STUB_H \ No newline at end of file diff --git a/ipc/native/src/core/include/ipc_process_skeleton.h b/ipc/native/src/core/include/ipc_process_skeleton.h index b9b9ec8..23756b6 100755 --- a/ipc/native/src/core/include/ipc_process_skeleton.h +++ b/ipc/native/src/core/include/ipc_process_skeleton.h @@ -29,6 +29,7 @@ #include "sys_binder.h" #ifndef CONFIG_IPC_SINGLE +#include "dbinder_callback_stub.h" #include "dbinder_session_object.h" #include "Session.h" #include "ISessionService.h" @@ -82,6 +83,7 @@ public: #ifndef CONFIG_IPC_SINGLE static uint32_t ConvertChannelID2Int(int64_t databusChannelId); + static bool IsHandleMadeByUser(uint32_t handle); #endif bool SetMaxWorkThread(int maxThreadNum); @@ -185,6 +187,10 @@ public: void DetachAppInfoToStubIndex(uint64_t stubIndex); bool AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, const std::string &deviceId, uint64_t stubIndex); bool QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, const std::string &deviceId, uint64_t stubIndex); + bool AttachDBinderCallbackStub(sptr rpcProxy, sptr stub); + bool DetachDBinderCallbackStubByProxy(sptr rpcProxy); + sptr QueryDBinderCallbackStub(sptr rpcProxy); + sptr QueryDBinderCallbackProxy(sptr stub); #endif public: @@ -230,6 +236,7 @@ private: std::shared_mutex stubRecvRefMutex_; std::shared_mutex appInfoToIndexMutex_; std::shared_mutex commAuthMutex_; + std::shared_mutex dbinderSentMutex_; std::map> seqNumberToThread_; std::map stubObjects_; @@ -241,6 +248,7 @@ private: std::map transTimes_; std::map>> dataInfoQueue_; // key is threadId std::map> appInfoToStubIndex_; + std::map, sptr> dbinderSentCallback; std::list idleDataThreads_; std::list> stubRecvRefs_; diff --git a/ipc/native/src/core/source/dbinder_callback_stub.cpp b/ipc/native/src/core/source/dbinder_callback_stub.cpp new file mode 100644 index 0000000..a9a18cc --- /dev/null +++ b/ipc/native/src/core/source/dbinder_callback_stub.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dbinder_callback_stub.h" + +#include +#include "sys_binder.h" +#include "string_ex.h" +#include "ipc_types.h" +#include "ipc_debug.h" +#include "log_tags.h" +#include "ipc_skeleton.h" +#include "ipc_process_skeleton.h" +#include "ipc_thread_skeleton.h" + +namespace OHOS { +#ifndef TITLE +#define TITLE __PRETTY_FUNCTION__ +#endif + +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "DBinderCallbackStub" }; +#define DBINDER_LOGE(fmt, args...) \ + (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) +#define DBINDER_LOGI(fmt, args...) \ + (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) + +DBinderCallbackStub::DBinderCallbackStub(const std::string &service, const std::string &device, + const std::string &localDevice, uint64_t stubIndex, uint32_t handle) + : IPCObjectStub(Str8ToStr16("DBinderCallback" + device + service)), + serviceName_(service), + deviceID_(device), + localDeviceID_(localDevice), + stubIndex_(stubIndex), + handle_(handle) +{ + DBINDER_LOGI("serviceName:%{public}s, deviceId:%{public}s, handle:%{public}u, stubIndex_:%{public}" PRIu64 "", + serviceName_.c_str(), deviceID_.c_str(), handle_, stubIndex_); +} + +DBinderCallbackStub::~DBinderCallbackStub() +{ + DBINDER_LOGI("DBinderCallbackStub delete"); +} + +const std::string &DBinderCallbackStub::GetServiceName() +{ + return serviceName_; +} + +const std::string &DBinderCallbackStub::GetDeviceID() +{ + return deviceID_; +} + +uint64_t DBinderCallbackStub::GetStubIndex() const +{ + return stubIndex_; +} + +int32_t DBinderCallbackStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int uid = IPCSkeleton::GetCallingUid(); + int pid = IPCSkeleton::GetCallingPid(); + if (uid < 0 || pid < 0) { + DBINDER_LOGE("uid or pid err"); + return DBINDER_SERVICE_PROCESS_PROTO_ERR; + } + sptr object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject(); + if (object == nullptr) { + DBINDER_LOGE("get sa object is null"); + return DBINDER_CALLBACK_READ_OBJECT_ERR; + } + IPCObjectProxy *samgr = reinterpret_cast(object.GetRefPtr()); + std::string sessionName = samgr->TransDataBusName(uid, pid); + if (sessionName.empty()) { + DBINDER_LOGE("grans session name failed"); + return DBINDER_SERVICE_WRONG_SESSION; + } + + MessageParcel authData, authReply; + MessageOption authOption; + if (!authData.WriteUint32(pid) || !authData.WriteUint32(uid) || !authData.WriteString(localDeviceID_) || + !authData.WriteUint64(stubIndex_)) { + DBINDER_LOGE("write to MessageParcel fail"); + return ERR_INVALID_DATA; + } + IRemoteInvoker *dbinderInvoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS); + if (dbinderInvoker == nullptr) { + DBINDER_LOGE("no databus thread and invoker"); + return RPC_DATABUS_INVOKER_ERR; + } + uint32_t err = dbinderInvoker->SendRequest(handle_, DBINDER_TRANS_COMMAUTH, authData, authReply, authOption); + if (err != ERR_NONE) { + DBINDER_LOGE("send auth info to remote fail"); + return BINDER_CALLBACK_AUTHCOMM_ERR; + } + DBINDER_LOGI("send to stub ok!stubIndex:%{public}" PRIu64 ", peerDevice = %{public}s, localDeviceID_ = %{public}s," + "serviceName_ = %{public}s, uid:%{public}d, pid:%{public}d, sessionName = %{public}s", + stubIndex_, deviceID_.c_str(), localDeviceID_.c_str(), serviceName_.c_str(), uid, pid, sessionName.c_str()); + if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(stubIndex_) || + !reply.WriteString(serviceName_) || !reply.WriteString(deviceID_) || !reply.WriteString(localDeviceID_) || + !reply.WriteString(sessionName)) { + DBINDER_LOGE("write to parcel fail"); + return ERR_INVALID_DATA; + } + return 0; +} + +int32_t DBinderCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int32_t result = ERR_NONE; + DBINDER_LOGI("code = %{public}u", code); + switch (code) { + case GET_PROTO_INFO: { + result = ProcessProto(code, data, reply, option); + break; + } + default: { + DBINDER_LOGI("unknown code = %{public}u", code); + result = DBINDER_CALLBACK_ERR; + break; + } + } + + return result; +} +} // namespace OHOS diff --git a/ipc/native/src/core/source/ipc_object_proxy.cpp b/ipc/native/src/core/source/ipc_object_proxy.cpp index 562d77f..c8acfbc 100755 --- a/ipc/native/src/core/source/ipc_object_proxy.cpp +++ b/ipc/native/src/core/source/ipc_object_proxy.cpp @@ -156,6 +156,33 @@ std::string IPCObjectProxy::GetDataBusName() return reply.ReadString(); } +std::string IPCObjectProxy::TransDataBusName(uint32_t uid, uint32_t pid) +{ + if (pid == static_cast(getpid())) { + ZLOGE(LABEL, "TransDataBusName can't write local pid. my/remotePid = %{public}u/%{public}u", getpid(), pid); + return std::string(""); + } + + MessageParcel data, reply; + MessageOption option; + if (!data.WriteUint32(pid) || !data.WriteUint32(uid)) { + ZLOGE(LABEL, "TransDataBusName write pid/uid = %{public}u/%{public}u failed", pid, uid); + return std::string(""); + } + uint32_t err = SendRequestInner(false, TRANS_DATABUS_NAME, data, reply, option); + if (err != ERR_NONE) { + ZLOGE(LABEL, "TransDataBusName transact return error = %{public}u", err); + return std::string(""); + } + + if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) { + ZLOGE(LABEL, "TransDataBusName normal binder"); + return std::string(""); + } + + return reply.ReadString(); +} + void IPCObjectProxy::OnFirstStrongRef(const void *objectId) { IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker(); diff --git a/ipc/native/src/core/source/ipc_object_stub.cpp b/ipc/native/src/core/source/ipc_object_stub.cpp index f28286a..24efaae 100755 --- a/ipc/native/src/core/source/ipc_object_stub.cpp +++ b/ipc/native/src/core/source/ipc_object_stub.cpp @@ -197,13 +197,14 @@ int IPCObjectStub::SendRequest(uint32_t code, MessageParcel &data, MessageParcel result = DecStubRefs(data, reply); break; } - case DBINDER_ADD_COMMAUTH: { + case DBINDER_ADD_COMMAUTH: + case DBINDER_TRANS_COMMAUTH: { if (IPCSkeleton::IsLocalCalling() || IPCSkeleton::GetCallingUid() >= ALLOWED_UID) { ZLOGE(LABEL, "%s: DBINDER_ADD_COMMAUTH unauthenticated user ", __func__); result = IPC_STUB_INVALID_DATA_ERR; break; } - result = AddAuthInfo(data, reply); + result = AddAuthInfo(data, reply, code); break; } case GET_UIDPID_INFO: { @@ -234,6 +235,15 @@ int IPCObjectStub::SendRequest(uint32_t code, MessageParcel &data, MessageParcel result = GrantDataBusName(code, data, reply, option); break; } + case TRANS_DATABUS_NAME: { + if (!IPCSkeleton::IsLocalCalling() || getuid() != SYSTEM_SERVER_UID) { + ZLOGE(LABEL, "TRANS_DATABUS_NAME message is excluded in sa manager"); + result = IPC_STUB_INVALID_DATA_ERR; + break; + } + result = TransDataBusName(code, data, reply, option); + break; + } #endif default: result = OnRemoteRequest(code, data, reply, option); @@ -428,7 +438,7 @@ int32_t IPCObjectStub::DecStubRefs(MessageParcel &data, MessageParcel &reply) return ERR_NONE; } -int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply) +int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code) { uint32_t remotePid = data.ReadUint32(); uint32_t remoteUid = data.ReadUint32(); @@ -448,12 +458,27 @@ int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply) ZLOGE(LABEL, "fail to attach comm auth info fail"); return IPC_STUB_INVALID_DATA_ERR; } + if (code == DBINDER_TRANS_COMMAUTH) { + uint64_t stubIndex = data.ReadUint64(); + if (stubIndex == 0) { + ZLOGE(LABEL, "fail to attach comm auth info fail"); + return BINDER_CALLBACK_STUBINDEX_ERR; + } + if (!current->AttachAppInfoToStubIndex(remotePid, remoteUid, remoteDeviceId, stubIndex)) { + ZLOGE(LABEL, "fail to add appinfo and stubIndex, maybe attach already"); + } + } return ERR_NONE; } std::string IPCObjectStub::GetDataBusName() { - sptr object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject(); + IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent(); + if (current == nullptr) { + ZLOGE(LABEL, "get current is null"); + return std::string(""); + } + sptr object = current->GetSAMgrObject(); if (object == nullptr) { ZLOGE(LABEL, "get object is null"); return std::string(""); @@ -480,6 +505,27 @@ int32_t IPCObjectStub::GrantDataBusName(uint32_t code, MessageParcel &data, Mess return ERR_NONE; } +int32_t IPCObjectStub::TransDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + uint32_t remotePid = data.ReadUint32(); + uint32_t remoteUid = data.ReadUint32(); + if (remotePid == static_cast(IPCSkeleton::GetCallingPid())) { + ZLOGE(LABEL, "pid/uid is invalid, pid = {public}%d, uid = {public}%d", remotePid, remoteUid); + return IPC_STUB_INVALID_DATA_ERR; + } + std::string sessionName = CreateDatabusName(remoteUid, remotePid); + if (sessionName.empty()) { + ZLOGE(LABEL, "pid/uid is invalid, pid = {public}%d, uid = {public}%d", remotePid, remoteUid); + return IPC_STUB_INVALID_DATA_ERR; + } + if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteString(sessionName)) { + ZLOGE(LABEL, "write to parcel fail"); + return IPC_STUB_INVALID_DATA_ERR; + } + + return ERR_NONE; +} + std::string IPCObjectStub::CreateDatabusName(int uid, int pid) { std::shared_ptr softbusManager = ISessionService::GetInstance(); diff --git a/ipc/native/src/core/source/ipc_process_skeleton.cpp b/ipc/native/src/core/source/ipc_process_skeleton.cpp index cbd6161..c9b40ac 100755 --- a/ipc/native/src/core/source/ipc_process_skeleton.cpp +++ b/ipc/native/src/core/source/ipc_process_skeleton.cpp @@ -335,6 +335,15 @@ std::string IPCProcessSkeleton::GetLocalDeviceID() return networkId; } +bool IPCProcessSkeleton::IsHandleMadeByUser(uint32_t handle) +{ + if (handle > DBINDER_HANDLE_BASE && handle < (DBINDER_HANDLE_BASE + DBINDER_HANDLE_BASE)) { + DBINDER_LOGE("handle = %{public}u is make by user, not kernel", handle); + return true; + } + return false; +} + uint32_t IPCProcessSkeleton::GetDBinderIdleHandle(uint64_t stubIndex) { std::unique_lock lockGuard(handleToIndexMutex_); @@ -605,7 +614,7 @@ std::shared_ptr IPCProcessSkeleton::PopDataInfoFromThread(con std::lock_guard lockGuard(dataQueueMutex_); if ((dataInfoQueue_[threadId]).size() == 0) { - return 0; + return nullptr; } std::shared_ptr processInfo = (dataInfoQueue_[threadId]).front(); @@ -1229,6 +1238,43 @@ void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub) std::unique_lock lockGuard(commAuthMutex_); commAuth_.remove_if(check); } + +bool IPCProcessSkeleton::AttachDBinderCallbackStub(sptr proxy, sptr stub) +{ + std::unique_lock lockGuard(dbinderSentMutex_); + auto result = dbinderSentCallback.insert(std::pair, sptr>(proxy, stub)); + return result.second; +} + +bool IPCProcessSkeleton::DetachDBinderCallbackStubByProxy(sptr proxy) +{ + std::unique_lock lockGuard(dbinderSentMutex_); + + return (dbinderSentCallback.erase(proxy) > 0); +} + +sptr IPCProcessSkeleton::QueryDBinderCallbackStub(sptr proxy) +{ + std::shared_lock lockGuard(dbinderSentMutex_); + auto it = dbinderSentCallback.find(proxy); + if (it != dbinderSentCallback.end()) { + return it->second; + } + return nullptr; +} + +sptr IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr stub) +{ + std::shared_lock lockGuard(dbinderSentMutex_); + for (auto it = dbinderSentCallback.begin(); it != dbinderSentCallback.end(); it++) { + if (it->second.GetRefPtr() == stub.GetRefPtr()) { + return it->first; + } + } + + return nullptr; +} + #endif #ifdef CONFIG_IPC_SINGLE } // namespace IPC_SINGLE diff --git a/ipc/native/src/core/source/message_parcel.cpp b/ipc/native/src/core/source/message_parcel.cpp index c02b915..5daee99 100755 --- a/ipc/native/src/core/source/message_parcel.cpp +++ b/ipc/native/src/core/source/message_parcel.cpp @@ -20,11 +20,30 @@ #include "ipc_debug.h" #include "iremote_object.h" #include "ipc_file_descriptor.h" +#include "ipc_process_skeleton.h" +#ifndef CONFIG_IPC_SINGLE +#include "dbinder_callback_stub.h" +#include "dbinder_session_object.h" +#endif #include "sys_binder.h" #include "ashmem.h" #include "securec.h" +#include "log_tags.h" namespace OHOS { +#ifndef TITLE +#define TITLE __PRETTY_FUNCTION__ +#endif + +#ifndef CONFIG_IPC_SINGLE +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "MessageParcel" }; +#define DBINDER_LOGE(fmt, args...) \ + (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) +#define DBINDER_LOGI(fmt, args...) \ + (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) +#endif + + MessageParcel::MessageParcel() : Parcel(), writeRawDataFd_(-1), @@ -71,15 +90,81 @@ MessageParcel::~MessageParcel() rawDataSize_ = 0; } + +#ifndef CONFIG_IPC_SINGLE +bool MessageParcel::WriteDBinderProxy(const sptr &object, uint32_t handle, uint64_t stubIndex) +{ + IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent(); + if (current == nullptr) { + DBINDER_LOGE("current is nullptr"); + return false; + } + std::shared_ptr sessionOfPeer = current->ProxyQueryDBinderSession(handle); + if (sessionOfPeer == nullptr) { + DBINDER_LOGE("sessionOfPeer is nullptr"); + return false; + } + std::string peerName = sessionOfPeer->GetServiceName(); + std::string peerId = sessionOfPeer->GetDeviceId(); + std::string localId = current->GetLocalDeviceID(); + sptr fakeStub = current->QueryDBinderCallbackStub(object); + if (fakeStub == nullptr) { + // note that cannot use this proxy's descriptor + fakeStub = new DBinderCallbackStub(peerName, peerId, localId, stubIndex, handle); + if (!current->AttachDBinderCallbackStub(object, fakeStub)) { + DBINDER_LOGE("save callback of fake stub failed"); + return false; + } + } + return WriteRemoteObject(fakeStub); +} +#endif + bool MessageParcel::WriteRemoteObject(const sptr &object) { + if (object == nullptr) { + return false; + } holders_.push_back(object); - return WriteObject(object); +#ifndef CONFIG_IPC_SINGLE + if (object->IsProxyObject()) { + const IPCObjectProxy *proxy = reinterpret_cast(object.GetRefPtr()); + const uint32_t handle = proxy ? proxy->GetHandle() : 0; + IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent(); + if (IPCProcessSkeleton::IsHandleMadeByUser(handle) && current != nullptr) { + DBINDER_LOGI("send dbinder object to local devices"); + /* this is a fake proxy which handle get by MakeRemoteHandle(), Not binder driver of kernel */ + uint64_t stubIndex = current->QueryHandleToIndex(handle); + if (stubIndex > 0) { + DBINDER_LOGI("this is dbinder proxy want to send anthor process in this device"); + return WriteDBinderProxy(object, handle, stubIndex); + } + } + } +#endif + auto result = WriteObject(object); + if (result == false) { + return result; + } + return result; } sptr MessageParcel::ReadRemoteObject() { - return ReadObject(); + sptr temp = ReadObject(); +#ifndef CONFIG_IPC_SINGLE + if (temp != nullptr && !temp->IsProxyObject()) { + // if this stub is a DBinderCallbackStub, return corresponding proxy + IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent(); + if (current != nullptr) { + sptr proxy = current->QueryDBinderCallbackProxy(temp); + if (proxy != nullptr) { + temp = proxy; + } + } + } +#endif + return temp; } bool MessageParcel::WriteFileDescriptor(int fd) diff --git a/ipc/native/src/mock/include/sys_binder.h b/ipc/native/src/mock/include/sys_binder.h index c3cb504..7bd14c4 100755 --- a/ipc/native/src/mock/include/sys_binder.h +++ b/ipc/native/src/mock/include/sys_binder.h @@ -43,13 +43,8 @@ enum { FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000, }; -#ifdef BINDER_IPC_32BIT -typedef __u32 binder_size_t; -typedef __u32 binder_uintptr_t; -#else typedef __u64 binder_size_t; typedef __u64 binder_uintptr_t; -#endif struct binder_object_header { __u32 type; }; @@ -101,11 +96,7 @@ struct binder_write_read { struct binder_version { __s32 protocol_version; }; -#ifdef BINDER_IPC_32BIT -#define BINDER_CURRENT_PROTOCOL_VERSION 7 -#else #define BINDER_CURRENT_PROTOCOL_VERSION 8 -#endif struct binder_node_debug_info { binder_uintptr_t ptr; binder_uintptr_t cookie; diff --git a/ipc/native/src/napi/src/napi_ashmem.cpp b/ipc/native/src/napi/src/napi_ashmem.cpp index fdeaecf..ef63667 100644 --- a/ipc/native/src/napi/src/napi_ashmem.cpp +++ b/ipc/native/src/napi/src/napi_ashmem.cpp @@ -56,6 +56,18 @@ napi_value NAPIAshmem::CreateAshmem(napi_env env, napi_callback_info info) napi_value argv[2] = { 0 }; napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); NAPI_ASSERT(env, argc == 2, "requires 2 parameter"); + napi_valuetype valueType = napi_null; + napi_typeof(env, argv[0], &valueType); + if (valueType != napi_string) { + ZLOGE(LOG_LABEL, "type mismatch for parameter 1"); + return nullptr; + } + napi_typeof(env, argv[1], &valueType); + if (valueType != napi_number) { + ZLOGE(LOG_LABEL, "type mismatch for parameter 2"); + return nullptr; + } + napi_value global = nullptr; napi_status status = napi_get_global(env, &global); NAPI_ASSERT(env, status == napi_ok, "get napi global failed"); diff --git a/ipc/native/test/unittest/common/BUILD.gn b/ipc/native/test/unittest/common/BUILD.gn index 66e753f..eca9bc1 100755 --- a/ipc/native/test/unittest/common/BUILD.gn +++ b/ipc/native/test/unittest/common/BUILD.gn @@ -36,8 +36,8 @@ ohos_unittest("IPCNativeUnitTest") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] @@ -61,8 +61,8 @@ ohos_unittest("IPCFileDescOpsTest") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", ] resource_config_file = diff --git a/ipc/test/auxiliary/native/BUILD.gn b/ipc/test/auxiliary/native/BUILD.gn index 9148061..321f702 100755 --- a/ipc/test/auxiliary/native/BUILD.gn +++ b/ipc/test/auxiliary/native/BUILD.gn @@ -35,8 +35,8 @@ ohos_shared_library("ipc_test_helper") { deps = [ "//utils/native/base:utils" ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] @@ -58,8 +58,8 @@ ohos_executable("ipc_server_test") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] @@ -81,8 +81,8 @@ ohos_executable("ipc_client_test") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] @@ -112,8 +112,8 @@ ohos_shared_library("ipc_test_helper_extra") { deps = [ "//utils/native/base:utils" ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] @@ -135,8 +135,8 @@ ohos_executable("ipc_server_test_extra") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] diff --git a/ipc/test/moduletest/native/BUILD.gn b/ipc/test/moduletest/native/BUILD.gn index 9b9fa87..0fe8e98 100755 --- a/ipc/test/moduletest/native/BUILD.gn +++ b/ipc/test/moduletest/native/BUILD.gn @@ -32,8 +32,8 @@ ohos_moduletest("IPCNativeFrameworksTest") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] diff --git a/ohos.build b/ohos.build index 415adb5..5fc6afb 100755 --- a/ohos.build +++ b/ohos.build @@ -2,11 +2,6 @@ "subsystem": "communication", "parts": { "ipc": { - "version": "1.0.0", - "interface-version": { - "ext-interface": "1.0", - "inter-device-interface": "1.0" - }, "module_list": [ "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", "//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single", @@ -75,11 +70,6 @@ ] }, "ipc_js": { - "version": "1.0.0", - "interface-version": { - "ext-interface": "1.0", - "inter-device-interface": "1.0" - }, "module_list": [ "//foundation/communication/ipc/interfaces/kits/js/napi:rpc" ], diff --git a/services/dbinder/test/BUILD.gn b/services/dbinder/test/BUILD.gn index 0fc1efc..cd6d1be 100755 --- a/services/dbinder/test/BUILD.gn +++ b/services/dbinder/test/BUILD.gn @@ -56,8 +56,8 @@ ohos_distributedtest("DbinderTest") { ] external_deps = [ - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", "samgr_standard:samgr_proxy", ] diff --git a/services/dbinder/test/distributedtest/include/dbinder_test_service.h b/services/dbinder/test/distributedtest/include/dbinder_test_service.h index 7d54e3e..534ac27 100755 --- a/services/dbinder/test/distributedtest/include/dbinder_test_service.h +++ b/services/dbinder/test/distributedtest/include/dbinder_test_service.h @@ -31,6 +31,8 @@ public: int PingService(std::u16string &serviceName) override; int TransProxyObject(int data, sptr &transObject, int operation, int &rep, int &withdrawRes) override; + int TransProxyObjectAgain(int data, sptr &transObject, int operation, int &rep, + int &withdrawRes) override; int TransStubObject(int data, sptr &transObject, int &rep, int &stubRep) override; int TransOversizedPkt(const std::string &dataStr, std::string &repStr) override; int ProxyTransRawData(int length) override; diff --git a/services/dbinder/test/distributedtest/include/dbinder_test_service_skeleton.h b/services/dbinder/test/distributedtest/include/dbinder_test_service_skeleton.h index b4ac69c..066552d 100755 --- a/services/dbinder/test/distributedtest/include/dbinder_test_service_skeleton.h +++ b/services/dbinder/test/distributedtest/include/dbinder_test_service_skeleton.h @@ -45,6 +45,8 @@ public: GET_REMOTE_STUB_OBJECT = 11, GET_REMOTE_DES_TIMES = 12, CLEAR_REMOTE_DES_TIMES = 13, + TRANS_OBJECT_OVER_DEVICE_OVER_PROCESS = 14, + TRANS_RPC_OBJECT_TO_LOCAL = 15, }; enum { @@ -66,6 +68,8 @@ public: virtual int ReverseIntDelayAsync(int data, int &rep) = 0; virtual int TransProxyObject(int data, sptr &transObject, int operation, int &rep, int &withdrawRes) = 0; + virtual int TransProxyObjectAgain(int data, sptr &transObject, int operation, int &rep, + int &withdrawRes) = 0; virtual int TransStubObject(int data, sptr &transObject, int &rep, int &stubRep) = 0; virtual int TransOversizedPkt(const std::string &dataStr, std::string &repStr) = 0; virtual int ProxyTransRawData(int lengths) = 0; @@ -100,6 +104,7 @@ private: int OnPingService(MessageParcel &data, MessageParcel &reply); int OnDelay(MessageParcel &data, MessageParcel &reply); int OnReceivedObject(MessageParcel &data, MessageParcel &reply); + int OnReceivedObjectTransAgain(MessageParcel &data, MessageParcel &reply); int OnReceivedStubObject(MessageParcel &data, MessageParcel &reply); int OnReceivedOversizedPkt(MessageParcel &data, MessageParcel &reply); int OnReceivedRawData(MessageParcel &data, MessageParcel &reply); @@ -126,6 +131,8 @@ public: int PingService(std::u16string &serviceName) override; int TransProxyObject(int data, sptr &transObject, int operation, int &rep, int &withdrawRes) override; + int TransProxyObjectAgain(int data, sptr &transObject, int operation, int &rep, + int &withdrawRes) override; int TransStubObject(int data, sptr &transObject, int &rep, int &stubRep) override; int TransOversizedPkt(const std::string &dataStr, std::string &repStr) override; int ProxyTransRawData(int length) override; diff --git a/services/dbinder/test/distributedtest/src/dbinder_distributed_test.cpp b/services/dbinder/test/distributedtest/src/dbinder_distributed_test.cpp index 9e692fa..9275bf8 100755 --- a/services/dbinder/test/distributedtest/src/dbinder_distributed_test.cpp +++ b/services/dbinder/test/distributedtest/src/dbinder_distributed_test.cpp @@ -1450,6 +1450,45 @@ HWTEST_F(DbinderTest, DbinderRemoteCall029, TestSize.Level3) SetCurrentTestCase(DBINDER_TEST_INIT); } +/* + * @tc.name: DbinderRemoteCall030 + * @tc.desc: Verify transferring objects between remote devices and tranfer to anthor process again + * @tc.type: FUNC + * @tc.require: SR000FL75G + */ +HWTEST_F(DbinderTest, DbinderRemoteCall030, TestSize.Level3) +{ + SetCurrentTestCase(DBINDER_TEST_REMOTE_CALL_011); + DBINDER_LOGI(""); + + /* + * @tc.steps: step1.Get a local binder object and a proxy pointing to remote stub. + * @tc.expected: step1.Get both objects successfully. + */ + sptr object = manager_->GetSystemAbility(RPC_TEST_SERVICE); + ASSERT_TRUE(object != nullptr); + sptr remoteObject = manager_->GetSystemAbility(RPC_TEST_SERVICE, serverId_); + ASSERT_TRUE(remoteObject != nullptr); + + sptr remoteTestService = iface_cast(remoteObject); + ASSERT_TRUE(remoteTestService != nullptr); + + /* + * @tc.steps: step2.Transfer the binder object to remote device repeatedly. + * @tc.expected: step2.Remote device receives the object and use it to communicate with server. + */ + for (int i = 0; i < MULTIPLEX_TIMES; i++) { + int reply = 0; + int withdrawRes = 0; + int result = remoteTestService->TransProxyObjectAgain(2021, object, DBinderTestServiceProxy::NOT_SAVE, + reply, withdrawRes); + EXPECT_EQ(result, 0); + EXPECT_EQ(reply, 1202); + } + + SetCurrentTestCase(DBINDER_TEST_INIT); +} + int main(int argc, char *argv[]) { g_pDistributetestEnv = new DistributeTestEnvironment("major.desc"); diff --git a/services/dbinder/test/distributedtest/src/dbinder_test_service.cpp b/services/dbinder/test/distributedtest/src/dbinder_test_service.cpp index 6153356..92507ed 100755 --- a/services/dbinder/test/distributedtest/src/dbinder_test_service.cpp +++ b/services/dbinder/test/distributedtest/src/dbinder_test_service.cpp @@ -125,6 +125,13 @@ int DBinderTestService::TransProxyObject(int data, sptr &transObj return 0; } +int DBinderTestService::TransProxyObjectAgain(int data, sptr &transObject, int operation, int &rep, + int &withdrawRes) +{ + DBINDER_LOGI("enter"); + return 0; +} + int DBinderTestService::TransStubObject(int data, sptr &transObject, int &rep, int &stubRep) { DBINDER_LOGI("enter %{public}s", __func__); diff --git a/services/dbinder/test/distributedtest/src/dbinder_test_service_skeleton.cpp b/services/dbinder/test/distributedtest/src/dbinder_test_service_skeleton.cpp index 116f4e7..f5743c2 100755 --- a/services/dbinder/test/distributedtest/src/dbinder_test_service_skeleton.cpp +++ b/services/dbinder/test/distributedtest/src/dbinder_test_service_skeleton.cpp @@ -15,9 +15,13 @@ #include "dbinder_test_service_skeleton.h" #include -#include "iremote_proxy.h" +#include "if_system_ability_manager.h" #include "ipc_skeleton.h" #include "ipc_object_proxy.h" +#include "iremote_proxy.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" namespace OHOS { using namespace OHOS::HiviewDFX; @@ -86,6 +90,24 @@ int DBinderTestServiceProxy::TransProxyObject(int data, sptr &tra return error; } +int DBinderTestServiceProxy::TransProxyObjectAgain(int data, sptr &transObject, int operation, int &rep, + int &withdrawRes) +{ + int error; + MessageOption option; + MessageParcel dataParcel, replyParcel; + if (!dataParcel.WriteInt32(data) || !dataParcel.WriteInt32(operation) || + !dataParcel.WriteRemoteObject(transObject)) { + DBINDER_LOGE("fail to write parcel"); + return ERR_INVALID_STATE; + } + error = Remote()->SendRequest(TRANS_OBJECT_OVER_DEVICE_OVER_PROCESS, dataParcel, replyParcel, option); + + rep = replyParcel.ReadInt32(); + withdrawRes = replyParcel.ReadInt32(); + return error; +} + int DBinderTestServiceProxy::TransStubObject(int data, sptr &transObject, int &rep, int &stubRep) { int error; @@ -417,9 +439,14 @@ int DBinderTestServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, case ONLY_DELAY: { return OnDelay(data, reply); } - case TRANS_OBJECT: { + case TRANS_OBJECT: + case TRANS_RPC_OBJECT_TO_LOCAL: { + DBINDER_LOGE("TestServiceStub::TRANS_RPC_OBJECT_TO_LOCAL?, cmd = %{public}d", code); return OnReceivedObject(data, reply); } + case TRANS_OBJECT_OVER_DEVICE_OVER_PROCESS: { + return OnReceivedObjectTransAgain(data, reply); + } case TRANS_STUB_OBJECT: { return OnReceivedStubObject(data, reply); } @@ -556,10 +583,10 @@ int DBinderTestServiceStub::OnReceivedObject(MessageParcel &data, MessageParcel DBINDER_LOGE("fail to write parcel"); return ERR_INVALID_STATE; } - HiLog::Info(LABEL, "%s:TRANSOBJECT: reqData=%d", __func__, reqData); + HiLog::Info(LABEL, "%{public}s:TRANSOBJECT: reqData=%{public}d", __func__, reqData); int ret = proxy->SendRequest(REVERSEINT, dataParcel, replyParcel, option); int reqResult = replyParcel.ReadInt32(); - HiLog::Info(LABEL, "%s:TRANSOBJECT: result=%d", __func__, reqResult); + HiLog::Info(LABEL, "%{public}s:TRANSOBJECT: result=%{public}d", __func__, reqResult); if (!reply.WriteInt32(reqResult)) { DBINDER_LOGE("fail to write parcel"); @@ -586,6 +613,54 @@ int DBinderTestServiceStub::OnReceivedObject(MessageParcel &data, MessageParcel return ret; } +int DBinderTestServiceStub::OnReceivedObjectTransAgain(MessageParcel &data, MessageParcel &reply) +{ + int32_t reqData = data.ReadInt32(); + int32_t operation = data.ReadInt32(); + sptr proxy = data.ReadRemoteObject(); + if (proxy == nullptr) { + DBINDER_LOGE("null proxy"); + return ERR_INVALID_STATE; + } + sptr manager_ = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (manager_ == nullptr) { + DBINDER_LOGE("null manager_"); + return ERR_INVALID_STATE; + } + HiLog::Info(LABEL, "%{public}s:OnReceivedObjectTransAgain-1: reqData=%{public}d", __func__, reqData); + + sptr object = manager_->GetSystemAbility(RPC_TEST_SERVICE2); + if (object == nullptr) { + DBINDER_LOGE("null object of RPC_TEST_SERVICE2"); + return ERR_INVALID_STATE; + } + + MessageOption option; + MessageParcel dataParcel, replyParcel; + if (!dataParcel.WriteInt32(reqData) || !dataParcel.WriteInt32(operation) || + !dataParcel.WriteRemoteObject(proxy)) { + DBINDER_LOGE("fail to write parcel"); + return ERR_INVALID_STATE; + } + HiLog::Info(LABEL, "%{public}s:OnReceivedObjectTransAgain-2: reqData=%{public}d", __func__, reqData); + int ret = object->SendRequest(TRANS_RPC_OBJECT_TO_LOCAL, dataParcel, replyParcel, option); + + int reqResult = replyParcel.ReadInt32(); + HiLog::Info(LABEL, "%{public}s:OnReceivedObjectTransAgain-3: result=%{public}d", __func__, reqResult); + + if (!reply.WriteInt32(reqResult)) { + DBINDER_LOGE("fail to write parcel"); + return ERR_INVALID_STATE; + } + HiLog::Info(LABEL, "%{public}s:OnReceivedObjectTransAgain-4: result=%{public}d", __func__, reqResult); + if (!reply.WriteInt32(0)) { + DBINDER_LOGE("fail to write parcel"); + return ERR_INVALID_STATE; + } + HiLog::Info(LABEL, "%{public}s:OnReceivedObjectTransAgain-5: result=%{public}d", __func__, reqResult); + return ret; +} + int DBinderTestServiceStub::OnReceivedStubObject(MessageParcel &data, MessageParcel &reply) { int32_t reqData = data.ReadInt32(); -- GitLab