提交 d7ef6229 编写于 作者: O openharmony_ci 提交者: Gitee

!55 OHOS_1230 sync code

Merge pull request !55 from zgit2021/master
......@@ -21,13 +21,12 @@ config("libipc_core_private_config") {
}
ohos_shared_library("ipc_core") {
include_dirs = [
"$SUBSYSTEM_DIR/utils/include",
]
include_dirs = [ "$SUBSYSTEM_DIR/utils/include" ]
sources = [
"$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",
......
......@@ -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();
......
......@@ -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
......
......@@ -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,12 @@ 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
......@@ -52,6 +52,9 @@ public:
};
private:
#ifndef CONFIG_IPC_SINGLE
bool WriteDBinderProxy(const sptr<IRemoteObject> &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;
......
......@@ -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:
......
/*
* 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 <string>
#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
......@@ -16,24 +16,26 @@
#ifndef OHOS_IPC_IPC_PROCESS_SKELETON_H
#define OHOS_IPC_IPC_PROCESS_SKELETON_H
#include <map>
#include <list>
#include <map>
#include <shared_mutex>
#include "refbase.h"
#include "iremote_object.h"
#include "ipc_thread_pool.h"
#include "nocopyable.h"
#include "invoker_rawdata.h"
#include "ipc_object_proxy.h"
#include "ipc_object_stub.h"
#include "invoker_rawdata.h"
#include "ipc_thread_pool.h"
#include "iremote_object.h"
#include "nocopyable.h"
#include "refbase.h"
#include "sys_binder.h"
#ifndef CONFIG_IPC_SINGLE
#include "comm_auth_info.h"
#include "dbinder_callback_stub.h"
#include "dbinder_session_object.h"
#include "Session.h"
#include "ISessionService.h"
#include "Session.h"
#include "stub_refcount_object.h"
#include "comm_auth_info.h"
using Communication::SoftBus::ISessionService;
using Communication::SoftBus::Session;
......@@ -82,6 +84,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 +188,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<IRemoteObject> rpcProxy, sptr<DBinderCallbackStub> stub);
bool DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> rpcProxy);
sptr<DBinderCallbackStub> QueryDBinderCallbackStub(sptr<IRemoteObject> rpcProxy);
sptr<IRemoteObject> QueryDBinderCallbackProxy(sptr<IRemoteObject> stub);
#endif
public:
......@@ -230,6 +237,7 @@ private:
std::shared_mutex stubRecvRefMutex_;
std::shared_mutex appInfoToIndexMutex_;
std::shared_mutex commAuthMutex_;
std::shared_mutex dbinderSentMutex_;
std::map<uint64_t, std::shared_ptr<ThreadMessageInfo>> seqNumberToThread_;
std::map<uint64_t, IRemoteObject *> stubObjects_;
......@@ -241,6 +249,7 @@ private:
std::map<IRemoteObject *, uint32_t> transTimes_;
std::map<std::thread::id, std::vector<std::shared_ptr<ThreadProcessInfo>>> dataInfoQueue_; // key is threadId
std::map<std::string, std::map<uint64_t, bool>> appInfoToStubIndex_;
std::map<sptr<IRemoteObject>, sptr<DBinderCallbackStub>> dbinderSentCallback;
std::list<std::thread::id> idleDataThreads_;
std::list<std::shared_ptr<StubRefCountObject>> stubRecvRefs_;
......
/*
* 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 <cinttypes>
#include "log_tags.h"
#include "ipc_debug.h"
#include "ipc_process_skeleton.h"
#include "ipc_skeleton.h"
#include "ipc_thread_skeleton.h"
#include "ipc_types.h"
#include "string_ex.h"
#include "sys_binder.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<IRemoteObject> object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject();
if (object == nullptr) {
DBINDER_LOGE("get sa object is null");
return DBINDER_CALLBACK_READ_OBJECT_ERR;
}
IPCObjectProxy *samgr = reinterpret_cast<IPCObjectProxy *>(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
......@@ -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<uint32_t>(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();
......
......@@ -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<IRemoteObject> object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject();
IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
if (current == nullptr) {
ZLOGE(LABEL, "get current is null");
return std::string("");
}
sptr<IRemoteObject> 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<uint32_t>(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<ISessionService> softbusManager = ISessionService::GetInstance();
......
......@@ -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<std::shared_mutex> lockGuard(handleToIndexMutex_);
......@@ -605,7 +614,7 @@ std::shared_ptr<ThreadProcessInfo> IPCProcessSkeleton::PopDataInfoFromThread(con
std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
if ((dataInfoQueue_[threadId]).size() == 0) {
return 0;
return nullptr;
}
std::shared_ptr<ThreadProcessInfo> processInfo = (dataInfoQueue_[threadId]).front();
......@@ -1229,6 +1238,43 @@ void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub)
std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
commAuth_.remove_if(check);
}
bool IPCProcessSkeleton::AttachDBinderCallbackStub(sptr<IRemoteObject> proxy, sptr<DBinderCallbackStub> stub)
{
std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
auto result = dbinderSentCallback.insert(std::pair<sptr<IRemoteObject>, sptr<DBinderCallbackStub>>(proxy, stub));
return result.second;
}
bool IPCProcessSkeleton::DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)
{
std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
return (dbinderSentCallback.erase(proxy) > 0);
}
sptr<DBinderCallbackStub> IPCProcessSkeleton::QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)
{
std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
auto it = dbinderSentCallback.find(proxy);
if (it != dbinderSentCallback.end()) {
return it->second;
}
return nullptr;
}
sptr<IRemoteObject> IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)
{
std::shared_lock<std::shared_mutex> 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
......
......@@ -14,17 +14,37 @@
*/
#include "message_parcel.h"
#include <unistd.h>
#include <sys/mman.h>
#include <unistd.h>
#include "ashmem.h"
#ifndef CONFIG_IPC_SINGLE
#include "dbinder_callback_stub.h"
#include "dbinder_session_object.h"
#endif
#include "ipc_debug.h"
#include "iremote_object.h"
#include "ipc_file_descriptor.h"
#include "sys_binder.h"
#include "ashmem.h"
#include "ipc_process_skeleton.h"
#include "iremote_object.h"
#include "log_tags.h"
#include "securec.h"
#include "sys_binder.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 +91,81 @@ MessageParcel::~MessageParcel()
rawDataSize_ = 0;
}
#ifndef CONFIG_IPC_SINGLE
bool MessageParcel::WriteDBinderProxy(const sptr<IRemoteObject> &object, uint32_t handle, uint64_t stubIndex)
{
IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
if (current == nullptr) {
DBINDER_LOGE("current is nullptr");
return false;
}
std::shared_ptr<DBinderSessionObject> 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<DBinderCallbackStub> 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<IRemoteObject> &object)
{
if (object == nullptr) {
return false;
}
holders_.push_back(object);
return WriteObject<IRemoteObject>(object);
#ifndef CONFIG_IPC_SINGLE
if (object->IsProxyObject()) {
const IPCObjectProxy *proxy = reinterpret_cast<const IPCObjectProxy *>(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<IRemoteObject>(object);
if (result == false) {
return result;
}
return result;
}
sptr<IRemoteObject> MessageParcel::ReadRemoteObject()
{
return ReadObject<IRemoteObject>();
sptr<IRemoteObject> temp = ReadObject<IRemoteObject>();
#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<IRemoteObject> proxy = current->QueryDBinderCallbackProxy(temp);
if (proxy != nullptr) {
temp = proxy;
}
}
}
#endif
return temp;
}
bool MessageParcel::WriteFileDescriptor(int fd)
......
......@@ -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;
......
......@@ -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");
......
......@@ -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"
],
......
......@@ -31,6 +31,8 @@ public:
int PingService(std::u16string &serviceName) override;
int TransProxyObject(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) override;
int TransProxyObjectAgain(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) override;
int TransStubObject(int data, sptr<IRemoteObject> &transObject, int &rep, int &stubRep) override;
int TransOversizedPkt(const std::string &dataStr, std::string &repStr) override;
int ProxyTransRawData(int length) override;
......
......@@ -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<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) = 0;
virtual int TransProxyObjectAgain(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) = 0;
virtual int TransStubObject(int data, sptr<IRemoteObject> &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<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) override;
int TransProxyObjectAgain(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes) override;
int TransStubObject(int data, sptr<IRemoteObject> &transObject, int &rep, int &stubRep) override;
int TransOversizedPkt(const std::string &dataStr, std::string &repStr) override;
int ProxyTransRawData(int length) override;
......
......@@ -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<IRemoteObject> object = manager_->GetSystemAbility(RPC_TEST_SERVICE);
ASSERT_TRUE(object != nullptr);
sptr<IRemoteObject> remoteObject = manager_->GetSystemAbility(RPC_TEST_SERVICE, serverId_);
ASSERT_TRUE(remoteObject != nullptr);
sptr<IDBinderTestService> remoteTestService = iface_cast<IDBinderTestService>(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");
......
......@@ -125,6 +125,13 @@ int DBinderTestService::TransProxyObject(int data, sptr<IRemoteObject> &transObj
return 0;
}
int DBinderTestService::TransProxyObjectAgain(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
int &withdrawRes)
{
DBINDER_LOGI("enter");
return 0;
}
int DBinderTestService::TransStubObject(int data, sptr<IRemoteObject> &transObject, int &rep, int &stubRep)
{
DBINDER_LOGI("enter %{public}s", __func__);
......
......@@ -14,10 +14,16 @@
*/
#include "dbinder_test_service_skeleton.h"
#include <cinttypes>
#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 +92,24 @@ int DBinderTestServiceProxy::TransProxyObject(int data, sptr<IRemoteObject> &tra
return error;
}
int DBinderTestServiceProxy::TransProxyObjectAgain(int data, sptr<IRemoteObject> &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<IRemoteObject> &transObject, int &rep, int &stubRep)
{
int error;
......@@ -417,9 +441,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 +585,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 +615,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<IRemoteObject> proxy = data.ReadRemoteObject();
if (proxy == nullptr) {
DBINDER_LOGE("null proxy");
return ERR_INVALID_STATE;
}
sptr<ISystemAbilityManager> 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<IRemoteObject> 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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册