feat: add ipc capi interface, remote object part

Signed-off-by: zhangchangqing <zhangchangqing5@huawei.com>
This commit is contained in:
zhangchangqing 2024-04-28 10:47:22 +08:00
parent 9b42730e3b
commit 04a10bb698
14 changed files with 1303 additions and 144 deletions

View File

@ -32,8 +32,11 @@ ohos_shared_library("ipc_ndk") {
sources = [
"$IPC_CORE_ROOT/src/c_api/source/ipc_cparcel.cpp",
"$IPC_CORE_ROOT/src/c_api/source/ipc_cremote_object.cpp",
"$IPC_CORE_ROOT/src/c_api/source/ipc_cskeleton.cpp",
"$IPC_CORE_ROOT/src/c_api/source/ipc_inner_object.cpp",
"$IPC_CORE_ROOT/src/c_api/source/ipc_internal_utils.cpp",
"$IPC_CORE_ROOT/src/c_api/source/ipc_remote_object_internal.cpp",
]
configs = [
@ -58,6 +61,7 @@ ohos_shared_library("ipc_ndk") {
]
install_images = [ system_base_dir ]
subsystem_name = "communication"
part_name = "ipc"
}

View File

@ -317,21 +317,14 @@ int OH_IPCParcel_ReadDouble(const OHIPCParcel *parcel, double *value);
int OH_IPCParcel_WriteString(OHIPCParcel *parcel, const char *str);
/**
* @brief OHIPCParcel对象读取字符串.
* @brief OHIPCParcel对象读取字符串strlen获取字符串长度
*
* @syscap SystemCapability.Communication.IPC.Core
* @param parcel OHIPCParcel对象的指针.
* @param str 使. \n
* .
* @param len str的数据长度.
* @param allocator str的内存分配器.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_PARCEL_READ_ERROR}.
* @param parcel OHIPCParcel对象的指针
* @return NULL
* @since 12
*/
int OH_IPCParcel_ReadString(const OHIPCParcel *parcel, char **str, int32_t *len,
OH_IPC_MemAllocator allocator);
const char* OH_IPCParcel_ReadString(const OHIPCParcel *parcel);
/**
* @brief OHIPCParcel对象写入指定长度的内存信息.
@ -348,21 +341,15 @@ int OH_IPCParcel_ReadString(const OHIPCParcel *parcel, char **str, int32_t *len,
int OH_IPCParcel_WriteBuffer(OHIPCParcel *parcel, const uint8_t *buffer, int32_t len);
/**
* @brief OHIPCParcel对象读取内存信息.
* @brief OHIPCParcel对象读取指定长度内存信息
*
* @syscap SystemCapability.Communication.IPC.Core
* @param parcel OHIPCParcel对象的指针.
* @param buffer 使. \n
* .
* @param len .
* @param allocator str的内存分配器.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_PARCEL_READ_ERROR}.
* @param parcel OHIPCParcel对象的指针
* @param len
* @return len超过parcel可读长度时返回NULL
* @since 12
*/
int OH_IPCParcel_ReadBuffer(const OHIPCParcel *parcel, uint8_t **buffer, int32_t *len,
OH_IPC_MemAllocator allocator);
const uint8_t* OH_IPCParcel_ReadBuffer(const OHIPCParcel *parcel, int32_t len);
/**
* @brief OHIPCParcel对象写入OHIPCRemoteStub对象.
@ -469,8 +456,8 @@ int OH_IPCParcel_WriteInterfaceToken(OHIPCParcel *parcel, const char *token);
* @param parcel OHIPCParcel对象的指针.
* @param token 使. \n
* .
* @param len .
* @param allocator str的内存分配器.
* @param len .
* @param allocator token的内存分配器.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_PARCEL_READ_ERROR}.

View File

@ -0,0 +1,263 @@
/*
* Copyright (c) 2024 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 NDK_INCLUDE_IPC_CREMOTE_OBJECT_H
#define NDK_INCLUDE_IPC_CREMOTE_OBJECT_H
/**
* @addtogroup OHIPCRemoteObject
* @{
*
* @brief C接口.
*
* @syscap SystemCapability.Communication.IPC.Core
* @since 12
*/
/**
* @file ipc_cremote_object.h
*
* @brief C接口.
*
* @library libipc_ndk.so
* @since 12
*/
#include <stdint.h>
#include "ipc_cparcel.h"
#ifdef __cplusplus
extern "C" {
#endif
struct OHIPCDeathRecipient;
/**
* @brief Stub端用于处理远端数据请求的回调函数.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param code :[0x01, 0x00ffffff].
* @param data .
* @param reply . \n
* .
* @param userData .
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* :[1909001, 1909999]. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INVALID_USER_ERROR_CODE}.
* @since 12
*/
typedef int (*OH_OnRemoteRequestCallback)(uint32_t code, const OHIPCParcel *data,
OHIPCParcel *reply, void *userData);
/**
* @brief Stub端用于监听对象销毁的回调函数.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param userData .
* @since 12
*/
typedef void (*OH_OnRemoteDestroyCallback)(void *userData);
/**
* @brief OHIPCRemoteStub对象.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param descriptor OHIPCRemoteStub对象描述符.
* @param requestCallback .
* @param destroyCallback .
* @param userData .
* @return OHIPCRemoteStub对象指针NULL.
* @since 12
*/
OHIPCRemoteStub* OH_IPCRemoteStub_Create(const char *descriptor, OH_OnRemoteRequestCallback requestCallback,
OH_OnRemoteDestroyCallback destroyCallback, void *userData);
/**
* @brief OHIPCRemoteStub对象.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param stub OHIPCRemoteStub对象指针.
* @since 12
*/
void OH_IPCRemoteStub_Destroy(OHIPCRemoteStub *stub);
/**
* @brief OHIPCRemoteProxy对象.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @since 12
*/
void OH_IPCRemoteProxy_Destroy(OHIPCRemoteProxy *proxy);
/**
* @brief IPC请求模式定义
*
* @since 12
*/
enum OH_IPC_RequestMode {
/**
*
*/
OH_IPC_REQUEST_MODE_SYNC = 0,
/**
*
*/
OH_IPC_REQUEST_MODE_ASYNC = 1,
};
/**
* @brief IPC消息选项定义.
*
* @since 12
*/
#pragma pack(4)
struct OH_IPC_MessageOption {
/**
*
*/
OH_IPC_RequestMode mode;
/**
* RPC预留参数IPC无效
*/
uint32_t timeout;
/**
*
*/
void* reserved;
};
#pragma pack()
/**
* @brief IPC消息发送函数.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @param code IPC命令字:[0x01,0x00ffffff].
* @param data .
* @param reply .
* @param option .
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* OHIPCRemoteStub对象死亡返回{@link OH_IPC_ErrorCode#OH_IPC_DEAD_REMOTE_OBJECT}. \n
* code超出范围返回{@link OH_IPC_ErrorCode#OH_IPC_CODE_OUT_OF_RANGE}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPC_SendRequest(const OHIPCRemoteProxy *proxy, uint32_t code, const OHIPCParcel *data,
OHIPCParcel *reply, const OH_IPC_MessageOption *option);
/**
* @brief Stub端获取接口描述符.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @param descriptor 使. \n
* .
* @param len descriptor的数据长度.
* @param allocator descriptor的内存分配器.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* OHIPCRemoteStub对象死亡返回{@link OH_IPC_ErrorCode#OH_IPC_DEAD_REMOTE_OBJECT}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_MEM_ALLOCATOR_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_PARCEL_READ_ERROR}.
* @since 12
*/
int OH_IPC_GetInterfaceDescriptor(OHIPCRemoteProxy *proxy, char **descriptor, int32_t *len,
OH_IPC_MemAllocator allocator);
/**
* @brief OHIPCRemoteStub对象死亡通知的回调函数类型.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param userData .
* @since 12
*/
typedef void (*OH_OnDeathRecipientCallback)(void *userData);
/**
* @brief OHIPCDeathRecipient对象销毁回调函数类型.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param userData .
* @since 12
*/
typedef void (*OH_OnDeathRecipientDestroyCallback)(void *userData);
/**
* @brief OHIPCRemoteStub对象死亡通知对象OHIPCDeathRecipient.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param deathRecipientCallback OHIPCRemoteStub对象死亡通知的回调处理函数.
* @param destroyCallback .
* @param userData .
* @return OHIPCDeathRecipient对象指针;NULL.
* @since 12
*/
OHIPCDeathRecipient* OH_IPCDeathRecipient_Create(OH_OnDeathRecipientCallback deathRecipientCallback,
OH_OnDeathRecipientDestroyCallback destroyCallback, void *userData);
/**
* @brief OHIPCDeathRecipient对象.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param recipient OHIPCDeathRecipient对象指针.
* @since 12
*/
void OH_IPCDeathRecipient_Destroy(OHIPCDeathRecipient *recipient);
/**
* @brief OHIPCRemoteProxy对象添加死亡监听OHIPCRemoteStub对象死亡的回调通知.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @param recipient .
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPCRemoteProxy_AddDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient);
/**
* @brief OHIPCRemoteProxy对象已经添加的死亡监听.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @param recipient .
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPCRemoteProxy_RemoveDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient);
/**
* @brief OHIPCRemoteProxy对象对应的远端OHIPCRemoteStub对象是否死亡.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param proxy OHIPCRemoteProxy对象指针.
* @return OHIPCRemoteStub对象死亡返回1; 0. OHIPCRemoteStub对象不存在1.
* @since 12
*/
int OH_IPC_IsRemoteDead(const OHIPCRemoteProxy *proxy);
#ifdef __cplusplus
}
#endif
/** @} */
#endif

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2024 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 NDK_INCLUDE_IPC_CSKELETON_H
#define NDK_INCLUDE_IPC_CSKELETON_H
/**
* @addtogroup OHIPCSkeleton
* @{
*
* @brief IPC框架tokenIdPID/UID线C接口.
*
* @syscap SystemCapability.Communication.IPC.Core
* @since 12
*/
/**
* @file ipc_cskeleton.h
*
* @brief IPC框架tokenIdPID/UID线C接口.
*
* @library libipc_ndk.so
* @since 12
*/
#include <stdint.h>
#include "ipc_cparcel.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief 线IPC工作线程池.
*
* @syscap SystemCapability.Communication.IPC.Core
* @since 12
*/
void OH_IPCSkeleton_JoinWorkThread(void);
/**
* @brief 线退IPC工作线程池.
*
* @syscap SystemCapability.Communication.IPC.Core
* @since 12
*/
void OH_IPCSkeleton_StopWorkThread(void);
/**
* @brief TokenId.IPC上下文中调用TokenId.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return TokenId.
* @since 12
*/
uint64_t OH_IPCSkeleton_GetCallingTokenId(void);
/**
* @brief TokenId.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return TokenId.
* @since 12
*/
uint64_t OH_IPCSkeleton_GetFirstTokenId(void);
/**
* @brief TokenId.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return TokenId.
* @since 12
*/
uint64_t OH_IPCSkeleton_GetSelfTokenId(void);
/**
* @brief ID.IPC上下文中调用ID.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return ID.
* @since 12
*/
uint64_t OH_IPCSkeleton_GetCallingPid(void);
/**
* @brief ID.IPC上下文中调用ID.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return ID.
* @since 12
*/
uint64_t OH_IPCSkeleton_GetCallingUid(void);
/**
* @brief .
*
* @syscap SystemCapability.Communication.IPC.Core
* @return 10.
* @since 12
*/
int OH_IPCSkeleton_IsLocalCalling(void);
/**
* @brief 线.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param maxThreadNum 线16[1, 32].
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPCSkeleton_SetMaxWorkThreadNum(const int maxThreadNum);
/**
* @brief tokenidUID和PID信息.
* OH_IPCSkeleton_SetCallingIdentity接口调用.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param identity 使.
* @param len identity的数据长度.
* @param allocator identity的内存分配器.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_MEM_ALLOCATOR_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPCSkeleton_ResetCallingIdentity(char **identity, int32_t *len, OH_IPC_MemAllocator allocator);
/**
* @brief IPC上下文中.
*
* @syscap SystemCapability.Communication.IPC.Core
* @param identity .OH_IPCSkeleton_ResetCallingIdentity的返回值.
* @return {@link OH_IPC_ErrorCode#OH_IPC_SUCCESS}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_CHECK_PARAM_ERROR}. \n
* {@link OH_IPC_ErrorCode#OH_IPC_INNER_ERROR}.
* @since 12
*/
int OH_IPCSkeleton_SetCallingIdentity(const char *identity);
/**
* @brief IPC请求.
*
* @syscap SystemCapability.Communication.IPC.Core
* @return IPC请求10.
* @since 12
*/
int OH_IPCSkeleton_IsHandlingTransaction(void);
#ifdef __cplusplus
}
#endif
/** @} */
#endif

View File

@ -17,10 +17,29 @@
#define NDK_INCLUDE_IPC_ERROR_CODE_H
/**
* @brief IPC错误码定义. \n
*
* @since 12
*/
* @addtogroup OHIPCErrorCode
* @{
*
* @brief Provides IPC error code define.
*
* @syscap SystemCapability.Communication.IPC.Core
* @since 12
*/
/**
* @file ipc_error_code.h
*
* @brief Provides IPC error code define.
*
* @library libipc_ndk.so
* @since 12
*/
/**
* @brief IPC错误码定义. \n
*
* @since 12
*/
enum OH_IPC_ErrorCode {
/**
*
@ -66,6 +85,15 @@ enum OH_IPC_ErrorCode {
*
*/
OH_IPC_ERROR_CODE_MAX = OH_IPC_ERROR_CODE_BASE + 1000,
/**
*
*/
OH_IPC_USER_ERROR_CODE_MIN = 1909000,
/**
*
*/
OH_IPC_USER_ERROR_CODE_MAX = 1909999,
};
/** @} */
#endif

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2024 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 NDK_INCLUDE_IPC_KIT_H
#define NDK_INCLUDE_IPC_KIT_H
#include "ipc_error_code.h"
#include "ipc_cparcel.h"
#include "ipc_cremote_object.h"
#include "ipc_cskeleton.h"
#endif

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 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 IPC_REMOTE_OBJECT_INTERNAL_H
#define IPC_REMOTE_OBJECT_INTERNAL_H
#include "ipc_cremote_object.h"
#include "iremote_object.h"
#include "ipc_object_stub.h"
#include "ipc_error_code.h"
static inline bool IsUserDefinedError(int error)
{
return (error >= OH_IPC_USER_ERROR_CODE_MIN) && (error <= OH_IPC_USER_ERROR_CODE_MAX);
}
static inline bool IsIpcErrorCode(int error)
{
return (error >= OH_IPC_ERROR_CODE_BASE) && (error <= OH_IPC_INNER_ERROR);
}
struct IPCDeathRecipient : public OHOS::IRemoteObject::DeathRecipient {
public:
IPCDeathRecipient(OH_OnDeathRecipientCallback deathRecipientCallback,
OH_OnDeathRecipientDestroyCallback destroyCallback, void *userData);
~IPCDeathRecipient();
virtual void OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> &object) override;
private:
OH_OnDeathRecipientCallback deathRecipientCallback_;
OH_OnDeathRecipientDestroyCallback destroyCallback_;
void *userData_;
};
struct OHIPCDeathRecipient {
OHOS::sptr<IPCDeathRecipient> recipient;
};
class OHIPCRemoteServiceStub : public OHOS::IPCObjectStub {
public:
OHIPCRemoteServiceStub(std::u16string &desc, OH_OnRemoteRequestCallback requestCallback,
OH_OnRemoteDestroyCallback destroyCallback, void *userData);
~OHIPCRemoteServiceStub();
int OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data,
OHOS::MessageParcel &reply, OHOS::MessageOption &option) override;
private:
OH_OnRemoteRequestCallback requestCallback_;
OH_OnRemoteDestroyCallback destroyCallback_;
void *userData_;
};
#endif

View File

@ -204,36 +204,13 @@ int OH_IPCParcel_WriteString(OHIPCParcel *parcel, const char *str)
return parcel->msgParcel->WriteString(std::string(str)) ? OH_IPC_SUCCESS : OH_IPC_PARCEL_WRITE_ERROR;
}
int OH_IPCParcel_ReadString(const OHIPCParcel *parcel, char **str, int32_t *len,
OH_IPC_MemAllocator allocator)
const char* OH_IPCParcel_ReadString(const OHIPCParcel *parcel)
{
if (!IsIPCParcelValid(parcel, __func__)
|| !IsMemoryParamsValid(str, len, allocator, __func__)) {
return OH_IPC_CHECK_PARAM_ERROR;
if (!IsIPCParcelValid(parcel, __func__)) {
return nullptr;
}
size_t readPosition = parcel->msgParcel->GetReadPosition();
std::string value;
if (!parcel->msgParcel->ReadString(value)) {
parcel->msgParcel->RewindRead(readPosition);
ZLOGE(LOG_LABEL, "read string failed!");
return OH_IPC_PARCEL_READ_ERROR;
}
int memLength = (value.length() + 1) * sizeof(char);
*str = static_cast<char*>(allocator(memLength));
if (*str == nullptr) {
parcel->msgParcel->RewindRead(readPosition);
ZLOGE(LOG_LABEL, "memory allocator failed!");
return OH_IPC_MEM_ALLOCATOR_ERROR;
}
if (memcpy_s(*str, memLength, value.c_str(), memLength) != EOK) {
parcel->msgParcel->RewindRead(readPosition);
ZLOGE(LOG_LABEL, "memcpy string failed, len:%{public}d", memLength);
return OH_IPC_PARCEL_READ_ERROR;
}
*len = value.length();
return OH_IPC_SUCCESS;
return parcel->msgParcel->ReadCString();
}
int OH_IPCParcel_WriteBuffer(OHIPCParcel *parcel, const uint8_t *buffer, int32_t len)
@ -243,10 +220,6 @@ int OH_IPCParcel_WriteBuffer(OHIPCParcel *parcel, const uint8_t *buffer, int32_t
}
size_t writePosition = parcel->msgParcel->GetWritePosition();
if (!parcel->msgParcel->WriteInt32(len)) {
ZLOGE(LOG_LABEL, "write buffer len failed! buffer len:%{public}d", len);
return OH_IPC_PARCEL_WRITE_ERROR;
}
if (!parcel->msgParcel->WriteBuffer(buffer, len)) {
ZLOGE(LOG_LABEL, "write buffer failed! buffer len:%{public}d", len);
parcel->msgParcel->RewindWrite(writePosition);
@ -255,40 +228,18 @@ int OH_IPCParcel_WriteBuffer(OHIPCParcel *parcel, const uint8_t *buffer, int32_t
return OH_IPC_SUCCESS;
}
int OH_IPCParcel_ReadBuffer(const OHIPCParcel *parcel, uint8_t **buffer, int32_t *len,
OH_IPC_MemAllocator allocator)
const uint8_t* OH_IPCParcel_ReadBuffer(const OHIPCParcel *parcel, int32_t len)
{
if (!IsIPCParcelValid(parcel, __func__)
|| !IsMemoryParamsValid(reinterpret_cast<char**>(buffer), len, allocator, __func__)) {
return OH_IPC_CHECK_PARAM_ERROR;
if (!IsIPCParcelValid(parcel, __func__)) {
return nullptr;
}
if (len <= 0 || len > parcel->msgParcel->GetReadableBytes()) {
ZLOGE(LOG_LABEL, "read buf len:%{public}d invalid! ReadableBytes:%{public}d",
len, parcel->msgParcel->GetReadableBytes());
return nullptr;
}
size_t readPosition = parcel->msgParcel->GetReadPosition();
int32_t length = 0;
if (!parcel->msgParcel->ReadInt32(length)) {
ZLOGE(LOG_LABEL, "read buffer len failed!");
return OH_IPC_PARCEL_READ_ERROR;
}
const uint8_t *readBuffer = parcel->msgParcel->ReadBuffer(length);
if (readBuffer == nullptr) {
ZLOGE(LOG_LABEL, "read buffer failed! buffer len:%{public}d", length);
parcel->msgParcel->RewindRead(readPosition);
return OH_IPC_PARCEL_READ_ERROR;
}
*buffer = static_cast<uint8_t*>(allocator(length));
if (*buffer == nullptr) {
ZLOGE(LOG_LABEL, "memory allocator failed!");
parcel->msgParcel->RewindRead(readPosition);
return OH_IPC_MEM_ALLOCATOR_ERROR;
}
if (memcpy_s(*buffer, length, readBuffer, length) != EOK) {
ZLOGE(LOG_LABEL, "memcpy string failed, len:%{public}d", length);
parcel->msgParcel->RewindRead(readPosition);
return OH_IPC_PARCEL_READ_ERROR;
}
*len = length;
return OH_IPC_SUCCESS;
return parcel->msgParcel->ReadBuffer(len);
}
template <typename T>
@ -425,6 +376,6 @@ int OH_IPCParcel_ReadInterfaceToken(const OHIPCParcel *parcel, char **token, int
ZLOGE(LOG_LABEL, "memcpy string failed, string len: %{public}d", memLength);
return OH_IPC_PARCEL_READ_ERROR;
}
*len = strToken.length();
*len = memLength;
return OH_IPC_SUCCESS;
}

View File

@ -0,0 +1,241 @@
/*
* Copyright (c) 2024 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 "ipc_cremote_object.h"
#include "ipc_inner_object.h"
#include "ipc_internal_utils.h"
#include "ipc_remote_object_internal.h"
#include "log_tags.h"
#include "ipc_debug.h"
#include "ipc_error_code.h"
#include "ipc_types.h"
#include "sys_binder.h"
#include <securec.h>
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, OHOS::LOG_ID_IPC_CAPI, "IPCRemoteObject" };
static constexpr uint32_t MIN_SEND_REQUEST_CODE = 0x01;
static constexpr uint32_t MAX_SEND_REQUEST_CODE = 0x00ffffff;
OHIPCRemoteStub* OH_IPCRemoteStub_Create(const char *descriptor, OH_OnRemoteRequestCallback requestCallback,
OH_OnRemoteDestroyCallback destroyCallback, void *userData)
{
if (descriptor == nullptr || requestCallback == nullptr) {
ZLOGE(LOG_LABEL, "check param error!");
return nullptr;
}
int len = strlen(descriptor);
if (len == 0 || len > MAX_PARCEL_LEN) {
ZLOGE(LOG_LABEL, "descriptor len:%{public}d is invalid!", len);
return nullptr;
}
std::u16string desc = OHOS::Str8ToStr16(std::string(descriptor));
if (desc.length() == 0 && len != 0) {
ZLOGE(LOG_LABEL, "convert descriptor to u16string failed: %{public}d", len);
return nullptr;
}
OHOS::sptr<OHIPCRemoteServiceStub> serviceStub(new (std::nothrow) OHIPCRemoteServiceStub(desc,
requestCallback, destroyCallback, userData));
if (serviceStub == nullptr) {
ZLOGE(LOG_LABEL, "new OHIPCRemoteServiceStub failed");
return nullptr;
}
OHIPCRemoteStub *stub = new (std::nothrow) OHIPCRemoteStub();
if (stub == nullptr) {
ZLOGE(LOG_LABEL, "new OHIPCRemoteStub failed");
return nullptr;
}
stub->remote = serviceStub;
return stub;
}
void OH_IPCRemoteStub_Destroy(OHIPCRemoteStub *stub)
{
if (stub != nullptr) {
stub->remote = nullptr;
delete stub;
}
}
void OH_IPCRemoteProxy_Destroy(OHIPCRemoteProxy *proxy)
{
if (proxy != nullptr) {
proxy->remote = nullptr;
delete proxy;
}
}
static int GetMessageFlag(OH_IPC_RequestMode mode)
{
return (mode == OH_IPC_REQUEST_MODE_ASYNC) ?
OHOS::MessageOption::TF_ASYNC : OHOS::MessageOption::TF_SYNC;
}
static constexpr struct {
int innerErrorCode;
int error;
} ERROR_MAP[] = {
{OHOS::IPC_PROXY_DEAD_OBJECT_ERR, OH_IPC_DEAD_REMOTE_OBJECT},
{OHOS::IPC_INVOKER_CONNECT_ERR, OH_IPC_INNER_ERROR},
{OHOS::IPC_PROXY_INVALID_CODE_ERR, OH_IPC_CODE_OUT_OF_RANGE},
{OHOS::IPC_STUB_WRITE_PARCEL_ERR, OH_IPC_PARCEL_WRITE_ERROR},
{OH_IPC_INVALID_USER_ERROR_CODE, OH_IPC_INVALID_USER_ERROR_CODE},
{BR_DEAD_REPLY, OH_IPC_DEAD_REMOTE_OBJECT},
{BR_FAILED_REPLY, OH_IPC_INNER_ERROR},
};
static int ConvertSendRequestError(int error)
{
if (error == OHOS::ERR_NONE) {
return OH_IPC_SUCCESS;
}
if (IsUserDefinedError(error) || IsIpcErrorCode(error)) {
return error;
}
static size_t arraySize = sizeof(ERROR_MAP) / sizeof(ERROR_MAP[0]);
for (size_t i = 0; i < arraySize; ++i) {
if (ERROR_MAP[i].innerErrorCode == error) {
return ERROR_MAP[i].error;
}
}
return OH_IPC_INNER_ERROR;
}
static bool IsCodeValid(uint32_t code)
{
return (code >= MIN_SEND_REQUEST_CODE) && (code <= MAX_SEND_REQUEST_CODE);
}
int OH_IPC_SendRequest(const OHIPCRemoteProxy *proxy, uint32_t code, const OHIPCParcel *data,
OHIPCParcel *reply, const OH_IPC_MessageOption *option)
{
if (!IsIPCRemoteProxyValid(proxy, __func__)
|| !IsIPCParcelValid(data, __func__)
|| (option != nullptr && option->reserved != nullptr)) {
return OH_IPC_CHECK_PARAM_ERROR;
}
if (!IsCodeValid(code)) {
ZLOGE(LOG_LABEL, "send request code:%{public}d out of range[%{public}d, %{public}d]",
code, MIN_SEND_REQUEST_CODE, MAX_SEND_REQUEST_CODE);
return OH_IPC_CODE_OUT_OF_RANGE;
}
OH_IPC_RequestMode mode = (option != nullptr) ? option->mode : OH_IPC_REQUEST_MODE_SYNC;
int ret = OH_IPC_SUCCESS;
OHOS::MessageOption msgOption(GetMessageFlag(mode));
if (IsIPCParcelValid(reply, __func__)) {
ret = proxy->remote->SendRequest(code, *data->msgParcel, *reply->msgParcel, msgOption);
} else if (mode == OH_IPC_REQUEST_MODE_SYNC) {
return OH_IPC_CHECK_PARAM_ERROR;
} else {
OHOS::MessageParcel msgReply;
ret = proxy->remote->SendRequest(code, *data->msgParcel, msgReply, msgOption);
}
return ConvertSendRequestError(ret);
}
int OH_IPC_GetInterfaceDescriptor(OHIPCRemoteProxy *proxy, char **descriptor, int32_t *len,
OH_IPC_MemAllocator allocator)
{
if (!IsIPCRemoteProxyValid(proxy, __func__)
|| !IsMemoryParamsValid(descriptor, len, allocator, __func__)) {
return OH_IPC_CHECK_PARAM_ERROR;
}
std::u16string u16string(proxy->remote->GetInterfaceDescriptor());
std::string value = OHOS::Str16ToStr8(u16string);
if (u16string.length() != 0 && value.length() == 0) {
ZLOGE(LOG_LABEL, "Str16ToStr8 failed! u16string len: %{public}u, string len: %{public}u",
static_cast<uint32_t>(u16string.length()), static_cast<uint32_t>(value.length()));
return OH_IPC_PARCEL_READ_ERROR;
}
int memLength = value.length() + 1;
*descriptor = static_cast<char*>(allocator(memLength));
if (*descriptor == nullptr) {
ZLOGE(LOG_LABEL, "memory allocator failed!");
return OH_IPC_MEM_ALLOCATOR_ERROR;
}
if (memcpy_s(*descriptor, memLength, value.c_str(), memLength) != EOK) {
ZLOGE(LOG_LABEL, "memcpy string failed");
return OH_IPC_PARCEL_READ_ERROR;
}
*len = memLength;
return OH_IPC_SUCCESS;
}
OHIPCDeathRecipient* OH_IPCDeathRecipient_Create(OH_OnDeathRecipientCallback deathRecipientCallback,
OH_OnDeathRecipientDestroyCallback destroyCallback, void *userData)
{
if (deathRecipientCallback == nullptr) {
ZLOGE(LOG_LABEL, "args must not be null");
return nullptr;
}
OHOS::sptr<IPCDeathRecipient> recipient(new (std::nothrow) IPCDeathRecipient(
deathRecipientCallback, destroyCallback, userData));
if (recipient == nullptr) {
ZLOGE(LOG_LABEL, "create IPCDeathRecipient object failed");
return nullptr;
}
OHIPCDeathRecipient *deathRecipient = new (std::nothrow) OHIPCDeathRecipient();
if (deathRecipient == nullptr) {
ZLOGE(LOG_LABEL, "create OHIPCDeathRecipient failed");
return nullptr;
}
deathRecipient->recipient = recipient;
return deathRecipient;
}
void OH_IPCDeathRecipient_Destroy(OHIPCDeathRecipient *recipient)
{
if (recipient != nullptr) {
recipient->recipient = nullptr;
delete recipient;
}
}
int OH_IPCRemoteProxy_AddDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient)
{
if (!IsIPCRemoteProxyValid(proxy, __func__)
|| recipient == nullptr
|| recipient->recipient == nullptr) {
return OH_IPC_CHECK_PARAM_ERROR;
}
return proxy->remote->AddDeathRecipient(recipient->recipient) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
}
int OH_IPCRemoteProxy_RemoveDeathRecipient(OHIPCRemoteProxy *proxy, OHIPCDeathRecipient *recipient)
{
if (!IsIPCRemoteProxyValid(proxy, __func__)
|| recipient == nullptr
|| recipient->recipient == nullptr) {
return OH_IPC_CHECK_PARAM_ERROR;
}
return proxy->remote->RemoveDeathRecipient(recipient->recipient) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
}
int OH_IPC_IsRemoteDead(const OHIPCRemoteProxy *proxy)
{
if (!IsIPCRemoteProxyValid(proxy, __func__)) {
return 1;
}
return proxy->remote->IsObjectDead() ? 1 : 0;
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2024 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 "ipc_cskeleton.h"
#include "ipc_error_code.h"
#include "log_tags.h"
#include "ipc_debug.h"
#include "ipc_skeleton.h"
#include "ipc_thread_skeleton.h"
#include <securec.h>
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, OHOS::LOG_ID_IPC_CAPI, "IPCSkeleton" };
static constexpr int MIN_THREAD_NUM = 1;
static constexpr int MAX_THREAD_NUM = 32;
void OH_IPCSkeleton_JoinWorkThread(void)
{
OHOS::IPCSkeleton::JoinWorkThread();
}
void OH_IPCSkeleton_StopWorkThread(void)
{
OHOS::IPCSkeleton::StopWorkThread();
}
uint64_t OH_IPCSkeleton_GetCallingTokenId(void)
{
return OHOS::IPCSkeleton::GetCallingFullTokenID();
}
uint64_t OH_IPCSkeleton_GetFirstTokenId(void)
{
return OHOS::IPCSkeleton::GetFirstFullTokenID();
}
uint64_t OH_IPCSkeleton_GetSelfTokenId(void)
{
return OHOS::IPCSkeleton::GetSelfTokenID();
}
uint64_t OH_IPCSkeleton_GetCallingPid(void)
{
return static_cast<uint64_t>(OHOS::IPCSkeleton::GetCallingPid());
}
uint64_t OH_IPCSkeleton_GetCallingUid(void)
{
return static_cast<uint64_t>(OHOS::IPCSkeleton::GetCallingUid());
}
int OH_IPCSkeleton_IsLocalCalling(void)
{
return OHOS::IPCSkeleton::IsLocalCalling() ? 1 : 0;
}
int OH_IPCSkeleton_SetMaxWorkThreadNum(const int maxThreadNum)
{
if (maxThreadNum < MIN_THREAD_NUM || maxThreadNum > MAX_THREAD_NUM) {
ZLOGE(LOG_LABEL, "Check param error!");
return OH_IPC_CHECK_PARAM_ERROR;
}
return OHOS::IPCSkeleton::SetMaxWorkThreadNum(maxThreadNum) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
}
int OH_IPCSkeleton_SetCallingIdentity(const char *identity)
{
if (identity == nullptr) {
ZLOGE(LOG_LABEL, "Check param error!");
return OH_IPC_CHECK_PARAM_ERROR;
}
std::string str = identity;
return OHOS::IPCSkeleton::SetCallingIdentity(str) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
}
int OH_IPCSkeleton_ResetCallingIdentity(char **identity, int32_t *len, OH_IPC_MemAllocator allocator)
{
if (identity == nullptr || len == nullptr || allocator == nullptr) {
ZLOGE(LOG_LABEL, "Check param error!");
return OH_IPC_CHECK_PARAM_ERROR;
}
std::string str(OHOS::IPCSkeleton::ResetCallingIdentity());
int length = str.length() + 1;
*identity = static_cast<char*>(allocator(length));
if (*identity == nullptr) {
ZLOGE(LOG_LABEL, "Memory allocator failed!");
return OH_IPC_MEM_ALLOCATOR_ERROR;
}
if (memcpy_s(*identity, length, str.c_str(), length) != EOK) {
ZLOGE(LOG_LABEL, "Memcpy string failed!");
return OH_IPC_INNER_ERROR;
}
*len = length;
return OH_IPC_SUCCESS;
}
int OH_IPCSkeleton_IsHandlingTransaction(void)
{
return (OHOS::IPCThreadSkeleton::GetActiveInvoker() != nullptr) ? 1 : 0;
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2024 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 "ipc_remote_object_internal.h"
#include "ipc_inner_object.h"
#include "message_parcel.h"
#include "log_tags.h"
#include "ipc_debug.h"
#include "ipc_error_code.h"
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, OHOS::LOG_ID_IPC_CAPI, "IPCRemoteObject" };
IPCDeathRecipient::IPCDeathRecipient(OH_OnDeathRecipientCallback deathRecipientCallback,
OH_OnDeathRecipientDestroyCallback destroyCallback, void *userData)
: deathRecipientCallback_(deathRecipientCallback), destroyCallback_(destroyCallback), userData_(userData)
{
}
IPCDeathRecipient::~IPCDeathRecipient()
{
if (destroyCallback_ != nullptr) {
destroyCallback_(userData_);
}
deathRecipientCallback_ = nullptr;
destroyCallback_ = nullptr;
userData_ = nullptr;
}
void IPCDeathRecipient::OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject>&)
{
if (deathRecipientCallback_ != nullptr) {
deathRecipientCallback_(userData_);
}
}
OHIPCRemoteServiceStub::OHIPCRemoteServiceStub(std::u16string &desc, OH_OnRemoteRequestCallback requestCallback,
OH_OnRemoteDestroyCallback destroyCallback, void *userData)
: IPCObjectStub(desc), requestCallback_(requestCallback), destroyCallback_(destroyCallback), userData_(userData)
{
}
OHIPCRemoteServiceStub::~OHIPCRemoteServiceStub()
{
if (destroyCallback_ != nullptr) {
(void)destroyCallback_(userData_);
}
destroyCallback_ = nullptr;
userData_ = nullptr;
requestCallback_ = nullptr;
}
int OHIPCRemoteServiceStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data,
OHOS::MessageParcel &reply, OHOS::MessageOption &)
{
if (requestCallback_ == nullptr) {
ZLOGE(LOG_LABEL, "Callback is null for code: %{public}u", code);
return OH_IPC_INNER_ERROR;
}
OHIPCParcel parcelData{ &data };
OHIPCParcel parcelReply{ &reply };
int err = requestCallback_(code, &parcelData, &parcelReply, userData_);
if (err != OH_IPC_SUCCESS
&& !IsIpcErrorCode(err)
&& !IsUserDefinedError(err)) {
ZLOGE(LOG_LABEL, "user define error code:%{public}d out of range[%{public}d, %{public}d]",
err, OH_IPC_USER_ERROR_CODE_MIN, OH_IPC_USER_ERROR_CODE_MAX);
err = OH_IPC_INVALID_USER_ERROR_CODE;
}
return err;
}

View File

@ -394,7 +394,10 @@ ohos_unittest("IpcCApiUnitTest") {
include_dirs = [ "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_core/include" ]
sources = [ "ipc_capi_parcel_unittest.cpp" ]
sources = [
"ipc_capi_parcel_unittest.cpp",
"ipc_capi_remote_object_unittest.cpp",
]
configs = [
"$SUBSYSTEM_DIR/config:ipc_util_config",

View File

@ -227,7 +227,7 @@ HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestDataInfo_001, TestSize.Level1)
{
OHIPCParcel *parcel = OH_IPCParcel_Create();
EXPECT_NE(parcel, nullptr);
EXPECT_EQ(OH_IPCParcel_GetDataSize(parcel), 0);
EXPECT_EQ(OH_IPCParcel_GetWritableBytes(parcel), DEFAULT_CAPACITY);
EXPECT_EQ(OH_IPCParcel_GetReadableBytes(parcel), 0);
@ -352,41 +352,16 @@ HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestReadWriteString_001, TestSize.L
OHIPCParcel *parcel = OH_IPCParcel_Create();
EXPECT_NE(parcel, nullptr);
void *data = nullptr;
int32_t len = 0;
// read without writing data
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, reinterpret_cast<char **>(&data), &len, LocalMemAllocator),
OH_IPC_PARCEL_READ_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadString(nullptr), nullptr);
// write string
EXPECT_EQ(OH_IPCParcel_WriteString(nullptr, STRING_CONSTANT), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_WriteString(parcel, nullptr), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_WriteString(parcel, STRING_CONSTANT), OH_IPC_SUCCESS);
// read after write
EXPECT_EQ(OH_IPCParcel_ReadString(nullptr, reinterpret_cast<char **>(&data), &len, LocalMemAllocator),
OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, nullptr, &len, LocalMemAllocator), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, reinterpret_cast<char **>(&data), nullptr, LocalMemAllocator),
OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, reinterpret_cast<char **>(&data), &len, nullptr),
OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, reinterpret_cast<char **>(&data), &len, LocalMemAllocator),
OH_IPC_SUCCESS);
EXPECT_EQ(strncmp((reinterpret_cast<char *>(data)), STRING_CONSTANT, strlen(STRING_CONSTANT)), 0);
if (data != nullptr) {
free(data);
}
OH_IPCParcel_Destroy(parcel);
}
HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestReadWriteString_002, TestSize.Level1)
{
OHIPCParcel *parcel = OH_IPCParcel_Create();
EXPECT_NE(parcel, nullptr);
void *data = nullptr;
int32_t len = 0;
EXPECT_EQ(OH_IPCParcel_WriteString(parcel, STRING_CONSTANT), OH_IPC_SUCCESS);
EXPECT_EQ(OH_IPCParcel_ReadString(parcel, reinterpret_cast<char **>(&data), &len, LocalMemAllocatorErr),
OH_IPC_MEM_ALLOCATOR_ERROR);
const char* str = OH_IPCParcel_ReadString(parcel);
EXPECT_EQ(strncmp(str, STRING_CONSTANT, strlen(STRING_CONSTANT)), 0);
EXPECT_EQ(strlen(STRING_CONSTANT), strlen(str));
OH_IPCParcel_Destroy(parcel);
}
@ -453,25 +428,11 @@ HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestReadWriteBuffer_001, TestSize.L
EXPECT_EQ(OH_IPCParcel_WriteBuffer(parcel, buffer, -1), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_WriteBuffer(parcel, buffer, len), OH_IPC_SUCCESS);
uint8_t *data = nullptr;
// abnormal parameters
EXPECT_EQ(OH_IPCParcel_ReadBuffer(nullptr, reinterpret_cast<uint8_t **>(&data), &len, LocalMemAllocator),
OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadBuffer(parcel, nullptr, &len, LocalMemAllocator), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadBuffer(parcel, reinterpret_cast<uint8_t **>(&data), nullptr,
LocalMemAllocator), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadBuffer(parcel, reinterpret_cast<uint8_t **>(&data), &len,
nullptr), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadBuffer(parcel, reinterpret_cast<uint8_t **>(&data), &len,
LocalMemAllocatorErr), OH_IPC_MEM_ALLOCATOR_ERROR);
EXPECT_EQ(OH_IPCParcel_ReadBuffer(nullptr, len), nullptr);
// normal scenes
EXPECT_EQ(OH_IPCParcel_ReadBuffer(parcel, reinterpret_cast<uint8_t **>(&data), &len,
LocalMemAllocator), OH_IPC_SUCCESS);
EXPECT_EQ(len, sizeof(buffer));
EXPECT_EQ(memcmp(buffer, data, len), 0);
if (data) {
delete data;
}
const uint8_t* readBuffer = OH_IPCParcel_ReadBuffer(parcel, len);
EXPECT_NE(readBuffer, nullptr);
EXPECT_EQ(memcmp(buffer, readBuffer, len), 0);
OH_IPCParcel_Destroy(parcel);
}
@ -479,10 +440,10 @@ HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestReadWriteInterfaceToken_001, Te
{
OHIPCParcel *parcel = OH_IPCParcel_Create();
EXPECT_NE(parcel, nullptr);
const char *buffer = "hello, world!";
EXPECT_EQ(OH_IPCParcel_WriteInterfaceToken(nullptr, buffer), OH_IPC_CHECK_PARAM_ERROR);
const char *token = "hello, world!";
EXPECT_EQ(OH_IPCParcel_WriteInterfaceToken(nullptr, token), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_WriteInterfaceToken(parcel, nullptr), OH_IPC_CHECK_PARAM_ERROR);
EXPECT_EQ(OH_IPCParcel_WriteInterfaceToken(parcel, buffer), OH_IPC_SUCCESS);
EXPECT_EQ(OH_IPCParcel_WriteInterfaceToken(parcel, token), OH_IPC_SUCCESS);
char *data = nullptr;
int32_t realLen = 0;
// abnormal parameters
@ -498,7 +459,8 @@ HWTEST_F(IpcCApiParcelUnitTest, OH_IPCParcel_TestReadWriteInterfaceToken_001, Te
// normal scenes
EXPECT_EQ(OH_IPCParcel_ReadInterfaceToken(parcel, reinterpret_cast<char **>(&data), &realLen,
LocalMemAllocator), OH_IPC_SUCCESS);
EXPECT_EQ(strcmp(buffer, data), 0);
EXPECT_EQ(strcmp(token, data), 0);
EXPECT_EQ(realLen, strlen(token) + 1);
// destroy object
if (data) {
delete data;

View File

@ -0,0 +1,264 @@
/*
* Copyright (C) 2024 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 <gtest/gtest.h>
#include <cstring>
#include <securec.h>
#include <mutex>
#include <condition_variable>
#include "if_system_ability_manager.h"
#include "ipc_error_code.h"
#include "ipc_inner_object.h"
#include "ipc_error_code.h"
#include "ipc_cparcel.h"
#include "ipc_cremote_object.h"
#include "ipc_test_helper.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "test_service_command.h"
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
static constexpr uint32_t ON_CALLBACK_REPLIED_INT = 1598311760;
class IpcCApiRemoteObjectUnitTest : public testing::Test {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_ID_TEST, "IpcCApiUnitTest" };
void ResetCallbackReply();
[[nodiscard]] int GetCallbackReply() const;
public:
static void OnRemoteObjectDestroy(void *userData);
static void OnDeathRecipientCallback(void *userData);
static void OnDeathRecipientDestroyCallback(void *userData);
static int OnRemoteRequestStub(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData);
private:
int callBackReply_{ 0 };
static inline IPCTestHelper *globalHelper_ = { nullptr };
};
void IpcCApiRemoteObjectUnitTest::SetUpTestCase()
{
if (globalHelper_ == nullptr) {
globalHelper_ = new IPCTestHelper();
bool res = globalHelper_->PrepareTestSuite();
ASSERT_TRUE(res);
}
}
void IpcCApiRemoteObjectUnitTest::TearDownTestCase()
{
if (globalHelper_ != nullptr) {
bool res = globalHelper_->TearDownTestSuite();
ASSERT_TRUE(res);
delete globalHelper_;
globalHelper_ = nullptr;
}
}
void IpcCApiRemoteObjectUnitTest::SetUp()
{
callBackReply_ = 0;
}
void IpcCApiRemoteObjectUnitTest::TearDown()
{}
void IpcCApiRemoteObjectUnitTest::ResetCallbackReply()
{
callBackReply_ = 0;
}
int IpcCApiRemoteObjectUnitTest::GetCallbackReply() const
{
return callBackReply_;
}
void IpcCApiRemoteObjectUnitTest::OnRemoteObjectDestroy(void *userData)
{
if (userData != nullptr) {
auto *test = static_cast<IpcCApiRemoteObjectUnitTest *>(userData);
test->callBackReply_ = ON_CALLBACK_REPLIED_INT;
}
}
void IpcCApiRemoteObjectUnitTest::OnDeathRecipientCallback(void *userData)
{
ZLOGD(LABEL, "OnDeathRecipientCallback modify callBackReply_");
if (userData != nullptr) {
auto *test = static_cast<IpcCApiRemoteObjectUnitTest *>(userData);
test->callBackReply_ = ON_CALLBACK_REPLIED_INT;
}
}
void IpcCApiRemoteObjectUnitTest::OnDeathRecipientDestroyCallback(void *userData)
{
if (userData != nullptr) {
auto *test = static_cast<IpcCApiRemoteObjectUnitTest *>(userData);
test->callBackReply_ = ON_CALLBACK_REPLIED_INT;
}
}
int IpcCApiRemoteObjectUnitTest::OnRemoteRequestStub(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply,
void *userData)
{
(void)userData;
(void)code;
(void)data;
(void)reply;
return 0;
}
static void* MemAllocator(int32_t len)
{
if (len <= 0) {
return nullptr;
}
void *buffer = malloc(len);
if (buffer == nullptr) {
return nullptr;
}
(void)memset_s(buffer, len, 0, len);
return buffer;
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, RemoteStub_Create_001, TestSize.Level1)
{
OHIPCRemoteStub *remote = OH_IPCRemoteStub_Create(nullptr, OnRemoteRequestStub, OnRemoteObjectDestroy, this);
EXPECT_EQ(remote, nullptr);
remote = OH_IPCRemoteStub_Create("RemoteStub_Create_001", nullptr, OnRemoteObjectDestroy, this);
EXPECT_EQ(remote, nullptr);
remote = OH_IPCRemoteStub_Create("RemoteStub_Create_001", OnRemoteRequestStub, nullptr, this);
EXPECT_NE(remote, nullptr);
OH_IPCRemoteStub_Destroy(remote);
remote = OH_IPCRemoteStub_Create("RemoteStub_Create_001", OnRemoteRequestStub, OnRemoteObjectDestroy, nullptr);
EXPECT_NE(remote, nullptr);
OH_IPCRemoteStub_Destroy(remote);
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, RemoteProxy_Destroy_001, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_NE(saMgr, nullptr);
sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_NE(object, nullptr);
OHIPCRemoteProxy *remoteProxy = CreateIPCRemoteProxy(object);
ASSERT_NE(remoteProxy, nullptr);
OH_IPCRemoteProxy_Destroy(remoteProxy);
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, DeathRecipient_Destroy_001, TestSize.Level1)
{
auto deathRecipient = OH_IPCDeathRecipient_Create(OnDeathRecipientCallback, OnDeathRecipientDestroyCallback, this);
ASSERT_NE(deathRecipient, nullptr);
ResetCallbackReply();
OH_IPCDeathRecipient_Destroy(deathRecipient);
EXPECT_EQ(GetCallbackReply(), ON_CALLBACK_REPLIED_INT);
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, RemoteProxy_AddDeathRecipient_001, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_NE(saMgr, nullptr);
sptr<IRemoteObject> objectServer = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_NE(objectServer, nullptr);
auto *remoteProxy = CreateIPCRemoteProxy(objectServer);
ASSERT_NE(remoteProxy, nullptr);
auto deathRecipient = OH_IPCDeathRecipient_Create(OnDeathRecipientCallback, OnDeathRecipientDestroyCallback,
this);
ASSERT_NE(deathRecipient, nullptr);
int ret = OH_IPCRemoteProxy_AddDeathRecipient(remoteProxy, deathRecipient);
EXPECT_EQ(ret, 0);
ResetCallbackReply();
res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
EXPECT_EQ(GetCallbackReply(), ON_CALLBACK_REPLIED_INT);
OH_IPCDeathRecipient_Destroy(deathRecipient);
OH_IPCRemoteProxy_Destroy(remoteProxy);
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, IsRemoteDead_001, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_NE(saMgr, nullptr);
sptr<IRemoteObject> objectServer = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_NE(objectServer, nullptr);
auto *remoteProxy = CreateIPCRemoteProxy(objectServer);
ASSERT_NE(remoteProxy, nullptr);
int ret = OH_IPC_IsRemoteDead(remoteProxy);
EXPECT_FALSE(ret);
res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
ret = OH_IPC_IsRemoteDead(remoteProxy);
EXPECT_TRUE(ret);
OH_IPCRemoteProxy_Destroy(remoteProxy);
}
HWTEST_F(IpcCApiRemoteObjectUnitTest, GetInterfaceDescriptor_001, TestSize.Level1)
{
IPCTestHelper helper;
bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
ASSERT_TRUE(res);
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_NE(saMgr, nullptr);
sptr<IRemoteObject> objectServer = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
ASSERT_NE(objectServer, nullptr);
auto *remoteProxy = CreateIPCRemoteProxy(objectServer);
ASSERT_NE(remoteProxy, nullptr);
char *descriptor = nullptr;
int32_t len = 0;
int ret = OH_IPC_GetInterfaceDescriptor(remoteProxy, &descriptor, &len, MemAllocator);
EXPECT_EQ(ret, 0);
EXPECT_EQ(strlen(descriptor) + 1, len);
EXPECT_GE(len, 0);
if (descriptor != nullptr) {
free(descriptor);
}
OH_IPCRemoteProxy_Destroy(remoteProxy);
}