未验证 提交 2133da38 编写于 作者: O openharmony_ci 提交者: Gitee

!260 ipc:add new interface of MessageParcelAppend

Merge pull request !260 from liubb_0516/master
...@@ -50,6 +50,7 @@ public: ...@@ -50,6 +50,7 @@ public:
{ {
needCloseFd_ = true; needCloseFd_ = true;
}; };
bool Append(MessageParcel &data);
private: private:
#ifndef CONFIG_IPC_SINGLE #ifndef CONFIG_IPC_SINGLE
......
...@@ -37,12 +37,44 @@ namespace OHOS { ...@@ -37,12 +37,44 @@ namespace OHOS {
#define TITLE __PRETTY_FUNCTION__ #define TITLE __PRETTY_FUNCTION__
#endif #endif
#ifdef CONFIG_IPC_SINGLE
using namespace IPC_SINGLE;
#endif
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "MessageParcel" }; static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "MessageParcel" };
#define DBINDER_LOGE(fmt, args...) \ #define DBINDER_LOGE(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
#define DBINDER_LOGI(fmt, args...) \ #define DBINDER_LOGI(fmt, args...) \
(void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args) (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
void AcquireObject(flat_binder_object *flat, const void *cookie)
{
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER:
if (flat->binder) {
reinterpret_cast<IRemoteObject *>(flat->cookie)->IncStrongRef(cookie);
}
break;
case BINDER_TYPE_HANDLE: {
IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
IRemoteObject *remoteObject = nullptr;
if (current != nullptr) {
remoteObject = current->QueryObject(current->MakeHandleDescriptor(flat->handle));
}
if (remoteObject != nullptr) {
remoteObject->IncStrongRef(cookie);
}
break;
}
case BINDER_TYPE_FD:
flat->handle = dup(flat->handle);
break;
default:
DBINDER_LOGE("binder object type is invalid.");
break;
}
}
MessageParcel::MessageParcel() MessageParcel::MessageParcel()
: Parcel(), : Parcel(),
writeRawDataFd_(-1), writeRawDataFd_(-1),
...@@ -422,4 +454,44 @@ sptr<Ashmem> MessageParcel::ReadAshmem() ...@@ -422,4 +454,44 @@ sptr<Ashmem> MessageParcel::ReadAshmem()
} }
return new (std::nothrow) Ashmem(fd, size); return new (std::nothrow) Ashmem(fd, size);
} }
bool MessageParcel::Append(MessageParcel &data)
{
size_t dataSize = data.GetDataSize();
if (dataSize == 0) {
DBINDER_LOGE("no data to append");
return true;
}
uintptr_t dataPtr = data.GetData();
size_t writeCursorOld = this->GetWritePosition();
if (!WriteBuffer(reinterpret_cast<void *>(dataPtr), dataSize)) {
DBINDER_LOGE("failed to append data with writebuffer.");
return false;
}
size_t objectSize = data.GetOffsetsSize();
if (objectSize == 0) {
return true;
}
binder_size_t objectOffsets = data.GetObjectOffsets();
auto *newObjectOffsets = reinterpret_cast<binder_size_t *>(objectOffsets);
for (size_t index = 0; index < objectSize; index++) {
if (EnsureObjectsCapacity()) {
size_t offset = writeCursorOld + newObjectOffsets[index];
if (!WriteObjectOffset(offset)) {
DBINDER_LOGE("failed to write object offset");
return false;
}
flat_binder_object *flat = reinterpret_cast<flat_binder_object *>(this->GetData() + offset);
if (flat == nullptr) {
DBINDER_LOGE("flat binder object is nullptr");
return false;
}
AcquireObject(flat, this);
} else {
DBINDER_LOGE("Failed to ensure parcel capacity");
return false;
}
}
return true;
}
} // namespace OHOS } // namespace OHOS
...@@ -46,6 +46,9 @@ public: ...@@ -46,6 +46,9 @@ public:
void TestAsyncDumpService() override; void TestAsyncDumpService() override;
int TestNestingSend(int sendCode, int &replyCode) override; int TestNestingSend(int sendCode, int &replyCode) override;
int TestAccessTokenID(int32_t ftoken_expected) override; int TestAccessTokenID(int32_t ftoken_expected) override;
int TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src) override;
int TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
MessageParcel &reply, bool withObject) override;
private: private:
int testFd_; int testFd_;
static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestService" }; static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestService" };
......
...@@ -47,6 +47,8 @@ public: ...@@ -47,6 +47,8 @@ public:
TRANS_ID_ASYNC_DUMP_SERVICE = 16, TRANS_ID_ASYNC_DUMP_SERVICE = 16,
TRANS_ID_NESTING_SEND = 17, TRANS_ID_NESTING_SEND = 17,
TRANS_ID_ACCESS_TOKENID = 18, TRANS_ID_ACCESS_TOKENID = 18,
TRANS_MESSAGE_PARCEL_ADDPED = 19,
TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT = 20,
}; };
public: public:
virtual int TestSyncTransaction(int data, int &reply, int delayTime = 0) = 0; virtual int TestSyncTransaction(int data, int &reply, int delayTime = 0) = 0;
...@@ -67,6 +69,9 @@ public: ...@@ -67,6 +69,9 @@ public:
virtual void TestAsyncDumpService() = 0; virtual void TestAsyncDumpService() = 0;
virtual int TestNestingSend(int sendCode, int &replyCode) = 0; virtual int TestNestingSend(int sendCode, int &replyCode) = 0;
virtual int TestAccessTokenID(int32_t ftoken_expected) = 0; virtual int TestAccessTokenID(int32_t ftoken_expected) = 0;
virtual int TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src) = 0;
virtual int TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
MessageParcel &reply, bool withObject) = 0;
public: public:
DECLARE_INTERFACE_DESCRIPTOR(u"test.ipc.ITestService"); DECLARE_INTERFACE_DESCRIPTOR(u"test.ipc.ITestService");
}; };
...@@ -105,6 +110,9 @@ public: ...@@ -105,6 +110,9 @@ public:
void TestAsyncDumpService() override; void TestAsyncDumpService() override;
int TestNestingSend(int sendCode, int &replyCode) override; int TestNestingSend(int sendCode, int &replyCode) override;
int TestAccessTokenID(int32_t ftoken_expected) override; int TestAccessTokenID(int32_t ftoken_expected) override;
int TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src) override;
int TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
MessageParcel &reply, bool withObject) override;
private: private:
static inline BrokerDelegator<TestServiceProxy> delegator_; static inline BrokerDelegator<TestServiceProxy> delegator_;
static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestServiceProxy" }; static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestServiceProxy" };
......
...@@ -192,6 +192,23 @@ int TestService::TestAccessTokenID(int32_t ftoken_expected) ...@@ -192,6 +192,23 @@ int TestService::TestAccessTokenID(int32_t ftoken_expected)
return 0; return 0;
} }
int TestService::TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src)
{
(void)dst;
(void)src;
return 0;
}
int TestService::TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
MessageParcel &reply, bool withObject)
{
(void)dst;
(void)src;
(void)reply;
(void)withObject;
return 0;
}
int TestService::TestFlushAsyncCalls(int count, int length) int TestService::TestFlushAsyncCalls(int count, int length)
{ {
return 0; return 0;
......
...@@ -426,6 +426,34 @@ int TestServiceProxy::TestAccessTokenID(int32_t ftoken_expected) ...@@ -426,6 +426,34 @@ int TestServiceProxy::TestAccessTokenID(int32_t ftoken_expected)
return 0; return 0;
} }
int TestServiceProxy::TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src)
{
bool res = dst.Append(src);
if (!res) {
ZLOGE(LABEL, "message parcel append without ipc failed");
return -1;
}
return 0;
}
int TestServiceProxy::TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
MessageParcel &reply, bool withObject)
{
bool res = dst.Append(src);
if (!res) {
ZLOGE(LABEL, "message parcel append with ipc failed");
return -1;
}
MessageOption option;
uint32_t code = TRANS_MESSAGE_PARCEL_ADDPED;
if (withObject) {
code = TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT;
}
int ret = Remote()->SendRequest(code, dst, reply, option);
ZLOGE(LABEL, "TestMessageParcelAppend with ipc sendrequest ret = %{public}d", ret);
return ret;
}
int TestServiceProxy::TestFlushAsyncCalls(int count, int length) int TestServiceProxy::TestFlushAsyncCalls(int count, int length)
{ {
int ret; int ret;
...@@ -646,6 +674,20 @@ int TestServiceStub::OnRemoteRequest(uint32_t code, ...@@ -646,6 +674,20 @@ int TestServiceStub::OnRemoteRequest(uint32_t code,
reply.WriteInt32(ftoken); reply.WriteInt32(ftoken);
break; break;
} }
case TRANS_MESSAGE_PARCEL_ADDPED: {
reply.WriteInt32(data.ReadInt32());
reply.WriteInt32(data.ReadInt32());
reply.WriteString(data.ReadString());
break;
}
case TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT: {
reply.WriteInt32(data.ReadInt32());
reply.WriteInt32(data.ReadInt32());
reply.WriteString(data.ReadString());
reply.WriteRemoteObject(data.ReadRemoteObject());
reply.WriteFileDescriptor(data.ReadFileDescriptor());
break;
}
default: default:
ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
break; break;
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include "system_ability_definition.h" #include "system_ability_definition.h"
#include "ipc_object_proxy.h" #include "ipc_object_proxy.h"
#include "directory_ex.h"
#include "foo_service.h"
#include "log_tags.h" #include "log_tags.h"
using namespace testing::ext; using namespace testing::ext;
...@@ -738,3 +741,145 @@ HWTEST_F(IPCNativeFrameworkTest, function_test_024, TestSize.Level1) ...@@ -738,3 +741,145 @@ HWTEST_F(IPCNativeFrameworkTest, function_test_024, TestSize.Level1)
thread->join(); thread->join();
} }
} }
/**
* @tc.name: function_test_025
* @tc.desc: Test messageparcel append in same process
* @tc.type: FUNC
* @tc.require: AR000H0FUK
*/
HWTEST_F(IPCNativeFrameworkTest, function_test_025, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_TRUE(saMgr != nullptr);
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_TRUE(object != nullptr);
sptr<ITestService> testService = iface_cast<ITestService>(object);
ASSERT_TRUE(testService != nullptr);
MessageParcel dstParcel, srcParcel;
int ret = testService->TestMessageParcelAppend(dstParcel, srcParcel);
EXPECT_EQ(ret, 0);
const int32_t num = 5767168;
const std::string strwrite1 =
"test for write string padded**********************************************************##################";
dstParcel.WriteInt32(num);
dstParcel.WriteString(strwrite1);
srcParcel.WriteInt32(num);
srcParcel.WriteString(strwrite1);
sptr<FooStub> fooCallback = new FooStub();
srcParcel.WriteRemoteObject(fooCallback->AsObject());
ret = testService->TestMessageParcelAppend(dstParcel, srcParcel);
EXPECT_EQ(ret, 0);
EXPECT_EQ(num, dstParcel.ReadInt32());
EXPECT_EQ(strwrite1, dstParcel.ReadString());
EXPECT_EQ(num, dstParcel.ReadInt32());
EXPECT_EQ(strwrite1, dstParcel.ReadString());
res = dstParcel.ReadRemoteObject();
ASSERT_TRUE(res);
ret = testService->TestMessageParcelAppend(srcParcel, dstParcel);
EXPECT_EQ(ret, 0);
EXPECT_EQ(num, srcParcel.ReadInt32());
EXPECT_EQ(strwrite1, srcParcel.ReadString());
res = srcParcel.ReadRemoteObject();
ASSERT_TRUE(res);
EXPECT_EQ(num, srcParcel.ReadInt32());
EXPECT_EQ(strwrite1, srcParcel.ReadString());
}
/**
* @tc.name: function_test_026
* @tc.desc: Test messageparcel append with ipc
* @tc.type: FUNC
* @tc.require: AR000H0FUK
*/
HWTEST_F(IPCNativeFrameworkTest, function_test_026, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_TRUE(saMgr != nullptr);
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_TRUE(object != nullptr);
sptr<ITestService> testService = iface_cast<ITestService>(object);
ASSERT_TRUE(testService != nullptr);
MessageParcel dstParcel, srcParcel, reply;
const int32_t num = 5767168;
dstParcel.WriteInt32(num);
srcParcel.WriteInt32(num);
const std::string strwrite1 =
"test for write string padded**********************************************************##################";
srcParcel.WriteString(strwrite1);
int ret = testService->TestMessageParcelAppendWithIpc(dstParcel, srcParcel, reply, false);
EXPECT_EQ(ret, 0);
EXPECT_EQ(num, reply.ReadInt32());
EXPECT_EQ(num, reply.ReadInt32());
EXPECT_EQ(strwrite1, reply.ReadString());
}
/**
* @tc.name: function_test_027
* @tc.desc: Test messageparcel append with ipc
* @tc.type: FUNC
* @tc.require: AR000H0FUK
*/
HWTEST_F(IPCNativeFrameworkTest, function_test_027, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_TRUE(saMgr != nullptr);
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_TRUE(object != nullptr);
sptr<ITestService> testService = iface_cast<ITestService>(object);
ASSERT_TRUE(testService != nullptr);
MessageParcel dstParcel, srcParcel, reply;
const int32_t num = 5767168;
dstParcel.WriteInt32(num);
srcParcel.WriteInt32(num);
const std::string strwrite1 =
"test for write string padded**********************************************************##################";
srcParcel.WriteString(strwrite1);
sptr<FooStub> fooCallback = new FooStub();
srcParcel.WriteRemoteObject(fooCallback->AsObject());
const std::string dirpath = "/data/test_dir";
res = ForceCreateDirectory(dirpath);
ASSERT_TRUE(res);
string filename = dirpath + "/test.txt";
int fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
EXPECT_GT(fd, 0);
res = srcParcel.WriteFileDescriptor(fd); // write fd
ASSERT_TRUE(res);
int ret = testService->TestMessageParcelAppendWithIpc(dstParcel, srcParcel, reply, true);
EXPECT_EQ(ret, 0);
EXPECT_EQ(num, reply.ReadInt32());
EXPECT_EQ(num, reply.ReadInt32());
EXPECT_EQ(strwrite1, reply.ReadString());
res = reply.ReadRemoteObject();
ASSERT_TRUE(res);
res = reply.ReadFileDescriptor();
ASSERT_TRUE(res);
RemoveFile(filename);
ForceRemoveDirectory(dirpath);
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册