diff --git a/uhdf2/hdi/BUILD.gn b/uhdf2/hdi/BUILD.gn index 667fdb2b9b676cdfbc3c47ab257748963fbaa5a6..1fba60251360eb4d57e6de4cfb5b2d32ae67f364 100644 --- a/uhdf2/hdi/BUILD.gn +++ b/uhdf2/hdi/BUILD.gn @@ -65,6 +65,7 @@ if (defined(ohos_lite)) { "src/servmgr_client.c", "src/servstat_listener.c", "src/servstat_listener_stub.cpp", + "src/stub_collector.cpp", ] deps = [ diff --git a/uhdf2/hdi/src/hdi_support.cpp b/uhdf2/hdi/src/hdi_support.cpp index d3b0c6919bf2540f3e542c1ac7bb9e443d9971cf..df99214ad7ea4da8c4125a7ec20ae0f88f99ffee 100644 --- a/uhdf2/hdi/src/hdi_support.cpp +++ b/uhdf2/hdi/src/hdi_support.cpp @@ -15,6 +15,8 @@ #include "hdi_support.h" #include +#include +#include #include #include #include @@ -39,10 +41,51 @@ constexpr size_t INTERFACE_NAME_INDEX = 3; static const std::regex reInfDesc("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\." "[V|v]([0-9]+)_([0-9]+)\\." "([a-zA-Z_][a-zA-Z0-9_]*)"); +using HdiImplInstanceFunc = void *(*)(void); +using HdiImplReleaseFunc = void (*)(void *); } // namespace -static int32_t ParseInterface(const std::string &desc, std::string &interface, uint32_t &versionMajor, - uint32_t &versionMinor) +static std::string TransFileName(const std::string &interfaceName) +{ + if (interfaceName.empty()) { + return interfaceName; + } + + std::string result; + for (size_t i = 0; i < interfaceName.size(); i++) { + char c = interfaceName[i]; + if (std::isupper(c) != 0) { + if (i > 1) { + result += '_'; + } + result += std::tolower(c); + } else { + result += c; + } + } + return result; +} + +struct HdiImpl { + HdiImpl() : handler(nullptr), constructor(nullptr), destructor(nullptr), useCount(0) {} + ~HdiImpl() = default; + void Unload() + { + if (handler != nullptr) { + dlclose(handler); + } + } + void *handler; + void *(*constructor)(void); + void (*destructor)(void *); + uint32_t useCount; +}; + +static std::map g_hdiConstructorMap; +static std::mutex g_loaderMutex; + +static int32_t ParseInterface( + const std::string &desc, std::string &interface, std::string &libpath, const char *serviceName) { std::smatch result; if (!std::regex_match(desc, result, reInfDesc)) { @@ -53,41 +96,33 @@ static int32_t ParseInterface(const std::string &desc, std::string &interface, u return HDF_FAILURE; } - versionMajor = std::stoul(result[INTERFACE_VERSION_MAJOR_INDEX]); - versionMinor = std::stoul(result[INTERFACE_VERSION_MINOR_INDEX]); + uint32_t versionMajor = std::stoul(result[INTERFACE_VERSION_MAJOR_INDEX]); + uint32_t versionMinor = std::stoul(result[INTERFACE_VERSION_MINOR_INDEX]); std::string interfaceName = result[INTERFACE_NAME_INDEX]; interface = interfaceName[0] == 'I' ? interfaceName.substr(1) : interfaceName; if (interface.empty()) { return HDF_FAILURE; } - - return HDF_SUCCESS; -} - -static std::string TransFileName(const std::string& interfaceName) -{ - if (interfaceName.empty()) { - return interfaceName; + char path[PATH_MAX + 1] = {0}; + char resolvedPath[PATH_MAX + 1] = {0}; + if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/lib%s_%s_%u.%u.z.so", HDI_SO_PATH, + TransFileName(interface).c_str(), serviceName, versionMajor, versionMinor) < 0) { + HDF_LOGE("%{public}s snprintf_s failed", __func__); + return HDF_FAILURE; } - std::string result; - for (size_t i = 0; i < interfaceName.size(); i++) { - char c = interfaceName[i]; - if (std::isupper(c) != 0) { - if (i > 1) { - result += '_'; - } - result += std::tolower(c); - } else { - result += c; - } + if (realpath(path, resolvedPath) == nullptr || strncmp(resolvedPath, HDI_SO_PATH, strlen(HDI_SO_PATH)) != 0) { + HDF_LOGE("%{public}s invalid hdi impl so name %{public}s", __func__, path); + return HDF_FAILURE; } - return result; + libpath = path; + return HDF_SUCCESS; } -/* service name: xxx_service - * interface descriptor name: ohos.hdi.sample.v1_0.IFoo +/* + * service name: xxx_service + * interface descriptor name: ohos.hdi.sample.v1_0.IFoo, the last two are version and interface base name * interface: Foo * versionMajor: 1 * versionMinor: 0 @@ -96,50 +131,65 @@ static std::string TransFileName(const std::string& interfaceName) */ void *LoadHdiImpl(const char *desc, const char *serviceName) { - char path[PATH_MAX + 1] = {0}; - char resolvedPath[PATH_MAX + 1] = {0}; - // interface descriptor name like "ohos.hdi.sample.v1_0.IFoo", the last two are version and interface base name - if (desc == nullptr || serviceName == nullptr) { - HDF_LOGE("%{public}s interface descriptor or service name is nullptr", __func__); - return nullptr; - } - - if (strlen(desc) == 0 || strlen(serviceName) == 0) { + if (desc == nullptr || serviceName == nullptr || strlen(desc) == 0 || strlen(serviceName) == 0) { HDF_LOGE("%{public}s invalid interface descriptor or service name", __func__); return nullptr; } std::string interfaceName; - uint32_t versionMajor = 0; - uint32_t versionMinor = 0; - if (ParseInterface(desc, interfaceName, versionMajor, versionMinor) != HDF_SUCCESS) { + std::string libpath; + if (ParseInterface(desc, interfaceName, libpath, serviceName) != HDF_SUCCESS) { HDF_LOGE("failed to parse hdi interface info from '%{public}s'", desc); return nullptr; } - if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/lib%s_%s_%u.%u.z.so", HDI_SO_PATH, - TransFileName(interfaceName).c_str(), serviceName, versionMajor, versionMinor) < 0) { - HDF_LOGE("%{public}s snprintf_s failed", __func__); - return nullptr; - } - if (realpath(path, resolvedPath) == nullptr || strncmp(resolvedPath, HDI_SO_PATH, strlen(HDI_SO_PATH)) != 0) { - HDF_LOGE("%{public}s invalid hdi impl so name %{public}s", __func__, path); - return nullptr; + std::lock_guard lock(g_loaderMutex); + auto constructor = g_hdiConstructorMap.find(libpath); + if (constructor != g_hdiConstructorMap.end()) { + return constructor->second.constructor(); } - HDF_LOGD("load interface impl lib: %{public}s", resolvedPath); - void *handler = dlopen(resolvedPath, RTLD_LAZY); - if (handler == nullptr) { + HdiImpl hdiImpl; + hdiImpl.handler = dlopen(libpath.c_str(), RTLD_LAZY); + if (hdiImpl.handler == nullptr) { HDF_LOGE("%{public}s dlopen failed %{public}s", __func__, dlerror()); return nullptr; } - std::string symName = interfaceName.append("ImplGetInstance"); - using HdiImplInstanceFunc = void *(*)(void); - HdiImplInstanceFunc hdiImplInstanceFunc = (HdiImplInstanceFunc)dlsym(handler, symName.data()); - if (hdiImplInstanceFunc == nullptr) { + std::string symName = interfaceName + "ImplGetInstance"; + hdiImpl.constructor = (HdiImplInstanceFunc)dlsym(hdiImpl.handler, symName.data()); + if (hdiImpl.constructor == nullptr) { HDF_LOGE("%{public}s dlsym failed %{public}s", __func__, dlerror()); - dlclose(handler); + hdiImpl.Unload(); return nullptr; } - return hdiImplInstanceFunc(); + std::string desSymName = interfaceName + "ImplRelease"; + hdiImpl.destructor = (HdiImplReleaseFunc)dlsym(hdiImpl.handler, desSymName.data()); + + void *implInstance = hdiImpl.constructor(); + if (implInstance == nullptr) { + HDF_LOGE("%{public}s no full hdi implementation in %{public}s", __func__, libpath.c_str()); + hdiImpl.Unload(); + } else { + g_hdiConstructorMap.emplace(std::make_pair(libpath, std::move(hdiImpl))); + } + return implInstance; +} + +void UnloadHdiImpl(const char *desc, const char *serviceName, void *impl) +{ + if (desc == nullptr || impl == nullptr) { + return; + } + + std::string interfaceName; + std::string libpath; + if (ParseInterface(desc, interfaceName, libpath, serviceName) != HDF_SUCCESS) { + HDF_LOGE("%{public}s: failed to parse hdi interface info from '%{public}s'", __func__, desc); + return; + } + std::lock_guard lock(g_loaderMutex); + auto constructor = g_hdiConstructorMap.find(libpath); + if (constructor != g_hdiConstructorMap.end() && constructor->second.destructor != nullptr) { + constructor->second.destructor(impl); + } } diff --git a/uhdf2/hdi/src/stub_collector.cpp b/uhdf2/hdi/src/stub_collector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5219a8b46a90579472f64dd57601f459d271c80 --- /dev/null +++ b/uhdf2/hdi/src/stub_collector.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2022 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 "stub_collector.h" +#include +#include +#include + +static std::map g_constructorMap; +static std::map g_stubMap; +static std::mutex g_consMapLock; +static std::mutex g_stubMapLock; + +void StubConstructorRegister(const char *ifDesc, struct StubConstructor *constructor) +{ + if (ifDesc == nullptr || constructor == nullptr) { + return; + } + + const std::lock_guard lock(g_consMapLock); + if (g_constructorMap.find(ifDesc) != g_constructorMap.end()) { + HDF_LOGE("repeat registration stub constructor for if %{public}s", ifDesc); + return; + } + g_constructorMap.emplace(std::make_pair(ifDesc, constructor)); + return; +} + +void StubConstructorUnregister(const char *ifDesc, struct StubConstructor *constructor) +{ + if (ifDesc == nullptr || constructor == nullptr) { + return; + } + + const std::lock_guard lock(g_consMapLock); + g_constructorMap.erase(ifDesc); + return; +} + +struct HdfRemoteService **StubCollectorGetOrNewObject(const char *ifDesc, void *servPtr) +{ + if (ifDesc == nullptr || servPtr == nullptr) { + return nullptr; + } + const std::lock_guard stublock(g_stubMapLock); + auto stub = g_stubMap.find(servPtr); + if (stub != g_stubMap.end()) { + return stub->second; + } + + HDF_LOGI("g_constructorMap size %{public}zu", g_constructorMap.size()); + for (auto &consruct : g_constructorMap) { + HDF_LOGI("g_constructorMap it: %{public}s", consruct.first.c_str()); + } + + const std::lock_guard lock(g_consMapLock); + auto constructor = g_constructorMap.find(ifDesc); + if (constructor == g_constructorMap.end()) { + HDF_LOGE("no stub constructor for %{public}s", ifDesc); + return nullptr; + } + + if (constructor->second->constructor == nullptr) { + HDF_LOGE("no stub constructor method for %{public}s", ifDesc); + return nullptr; + } + + HdfRemoteService **stubObject = constructor->second->constructor(servPtr); + if (stubObject == nullptr) { + HDF_LOGE("failed to construct stub obj %{public}s", ifDesc); + return nullptr; + } + g_stubMap.insert(std::make_pair(servPtr, stubObject)); + return stubObject; +} + +void StubCollectorRemoveObject(const char *ifDesc, void *servPtr) +{ + if (ifDesc == nullptr || servPtr == nullptr) { + return; + } + + const std::lock_guard stublock(g_stubMapLock); + auto stub = g_stubMap.find(servPtr); + if (stub == g_stubMap.end()) { + return; + } + const std::lock_guard lock(g_consMapLock); + auto constructor = g_constructorMap.find(ifDesc); + if (constructor == g_constructorMap.end()) { + HDF_LOGE("no stub constructor for %{public}s", ifDesc); + return; + } + + if (constructor->second->destructor != nullptr) { + constructor->second->destructor(stub->second); + } + + g_stubMap.erase(servPtr); +} diff --git a/uhdf2/hdi/test/BUILD.gn b/uhdf2/hdi/test/BUILD.gn index 65aac55c136e85f175a2a1df612b29bd20df5786..3a2f9db11dcf0a414979e5071e77d381cddf0497 100644 --- a/uhdf2/hdi/test/BUILD.gn +++ b/uhdf2/hdi/test/BUILD.gn @@ -65,7 +65,5 @@ group("unittest") { deps = [ ":HdiServiceManagerTest", ":HdiServiceManagerTestCC", - "hdi_sample/sample_client_cpp/unittest:sample_client_cpp", - "hdi_sample/sample_service_cpp:sample_service_cpp", ] } diff --git a/uhdf2/hdi/test/hdi_sample/sample_client_c/BUILD.gn b/uhdf2/hdi/test/hdi_sample/sample_client_c/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6b763403e5aae54b9554094a367e9621b23d5479 --- /dev/null +++ b/uhdf2/hdi/test/hdi_sample/sample_client_c/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2022 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. + +import("//build/test.gni") +import("//drivers/adapter/uhdf2/uhdf.gni") + +module_output_path = "hdf/hdi" + +ohos_unittest("HdiSampleTestC") { + module_out_path = module_output_path + sources = [ "sample_client_c_test.cpp" ] + + deps = [ + "$hdf_uhdf_path/hdi:libhdi", + "$hdf_uhdf_path/utils:libhdf_utils", + "unittest:libsample_client_c", + "//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "samgr_standard:samgr_proxy", + "utils_base:utils", + ] +} diff --git a/uhdf2/hdi/test/hdi_sample/sample_client_c/sample_client_c_test.cpp b/uhdf2/hdi/test/hdi_sample/sample_client_c/sample_client_c_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..95b3e04f535f7247ce5d83c3a66ac4505da004f7 --- /dev/null +++ b/uhdf2/hdi/test/hdi_sample/sample_client_c/sample_client_c_test.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2022 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ifoo.h" +#include "isample.h" +#include "isample_callback.h" + +using namespace OHOS; +using namespace testing::ext; + +#define HDF_LOG_TAG sample_client_c_test + +constexpr const char *TEST_SERVICE_NAME = "sample_driver_service"; + +class SampleHdiCTest : public testing::Test { +public: + static void SetUpTestCase() + { + auto devmgr = HDIDeviceManagerGet(); + if (devmgr != nullptr) { + devmgr->LoadDevice(devmgr, TEST_SERVICE_NAME); + HDIDeviceManagerRelease(devmgr); + } + } + static void TearDownTestCase() + { + auto devmgr = HDIDeviceManagerGet(); + if (devmgr != nullptr) { + devmgr->UnloadDevice(devmgr, TEST_SERVICE_NAME); + HDIDeviceManagerRelease(devmgr); + } + } + void SetUp() {} + void TearDown() {} +}; + +// IPC mode get interface object +HWTEST_F(SampleHdiCTest, HdiCTest001, TestSize.Level1) +{ + struct ISample *sampleService = ISampleGetInstance(TEST_SERVICE_NAME, false); + ASSERT_TRUE(sampleService != nullptr); + + struct IFoo *fooInterface = nullptr; + int ret = sampleService->GetInterface(sampleService, &fooInterface); + ASSERT_EQ(ret, 0); + ASSERT_NE(fooInterface, nullptr); + + ret = fooInterface->FooEvent(fooInterface, 1); + ASSERT_EQ(ret, 0); + + bool value = false; + ret = sampleService->PingTest(sampleService, true, &value); + ASSERT_EQ(ret, 0); + ASSERT_EQ(value, true); + + IFooRelease(true, fooInterface); + ISampleRelease(false, sampleService); +} + +// passthrough mode get interface object +HWTEST_F(SampleHdiCTest, HdiCTest002, TestSize.Level1) +{ + struct ISample *sampleService = ISampleGet(true); + ASSERT_TRUE(sampleService != nullptr); + + struct IFoo *fooInterface = nullptr; + int ret = sampleService->GetInterface(sampleService, &fooInterface); + ASSERT_EQ(ret, 0); + ASSERT_NE(fooInterface, nullptr); + + ret = fooInterface->FooEvent(fooInterface, 1); + ASSERT_EQ(ret, 0); + + bool value = false; + ret = sampleService->PingTest(sampleService, true, &value); + ASSERT_EQ(ret, 0); + ASSERT_EQ(value, true); + + IFooRelease(true, fooInterface); + ISampleRelease(true, sampleService); +} + +struct SampleCallbackImpl { + struct ISampleCallback interface; + bool called; +}; + +static int32_t SampleCallbackPingTest(struct ISampleCallback *self, int event) +{ + if (self == nullptr) { + return HDF_ERR_INVALID_PARAM; + } + struct SampleCallbackImpl *callback = CONTAINER_OF(self, struct SampleCallbackImpl, interface); + callback->called = true; + HDF_LOGI("%{public}s called, event = %{public}d", __func__, event); + return HDF_SUCCESS; +} + +// ipc mode set callback +HWTEST_F(SampleHdiCTest, HdiCTest003, TestSize.Level1) +{ + struct ISample *sampleService = ISampleGetInstance(TEST_SERVICE_NAME, false); + ASSERT_TRUE(sampleService != nullptr); + + bool value = false; + int ret = sampleService->PingTest(sampleService, true, &value); + ASSERT_EQ(ret, 0); + ASSERT_EQ(value, true); + + struct SampleCallbackImpl callback; + callback.interface.PingTest = SampleCallbackPingTest; + ret = sampleService->SetCallback(sampleService, &callback.interface); + + uint32_t retry = 0; + constexpr int WAIT_COUNT = 200; + while (!callback.called && retry < WAIT_COUNT) { + retry++; + OsalMSleep(1); + } + + ASSERT_TRUE(callback.called); + ISampleRelease(false, sampleService); +} + +// passthrougt mode set callback +HWTEST_F(SampleHdiCTest, HdiCTest004, TestSize.Level1) +{ + struct ISample *sampleService = ISampleGet(true); + ASSERT_TRUE(sampleService != nullptr); + + bool value = false; + int ret = sampleService->PingTest(sampleService, true, &value); + ASSERT_EQ(ret, 0); + ASSERT_EQ(value, true); + struct SampleCallbackImpl callback; + callback.interface.PingTest = SampleCallbackPingTest; + ret = sampleService->SetCallback(sampleService, &callback.interface); + uint32_t retry = 0; + + constexpr int WAIT_COUNT = 20; + while (!callback.called && retry < WAIT_COUNT) { + retry++; + OsalMSleep(1); + } + + ASSERT_TRUE(callback.called); + ISampleRelease(true, sampleService); +} + +struct SampleDeathRecipient { + struct HdfDeathRecipient recipient; + bool called; +}; + +static void SampleOnRemoteDied(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote) +{ + HDF_LOGI("sample service dead"); + if (deathRecipient == nullptr || remote == nullptr) { + return; + } + struct SampleDeathRecipient *sampleRecipient = CONTAINER_OF(deathRecipient, struct SampleDeathRecipient, recipient); + sampleRecipient->called = true; +} + +// IPC mode add DeathRecipient +HWTEST_F(SampleHdiCTest, HdiCTest005, TestSize.Level1) +{ + struct ISample *sampleService = ISampleGetInstance(TEST_SERVICE_NAME, false); + ASSERT_TRUE(sampleService != nullptr); + + struct SampleDeathRecipient deathRecipient = { + .recipient = { + .OnRemoteDied = SampleOnRemoteDied, + }, + .called = false, + }; + + ASSERT_NE(sampleService->AsObject, nullptr); + struct HdfRemoteService *remote = sampleService->AsObject(sampleService); + ASSERT_NE(remote, nullptr); + + HdfRemoteAdapterAddDeathRecipient(remote, &deathRecipient.recipient); + TearDownTestCase(); + + int retry = 0; + constexpr int WAIT_COUNT = 200; + while (!deathRecipient.called && retry < WAIT_COUNT) { + retry++; + OsalMSleep(1); + } + ASSERT_TRUE(deathRecipient.called); + + HdfRemoteAdapterRemoveDeathRecipient(remote, &deathRecipient.recipient); + ISampleRelease(true, sampleService); +} \ No newline at end of file diff --git a/uhdf2/include/hdi/hdi_support.h b/uhdf2/include/hdi/hdi_support.h index d4c301ef52f91e2fd3373b3c71cd6e38ed0b710a..b2a0ddae0e50d4399f54e1324201b1c7c189d93b 100644 --- a/uhdf2/include/hdi/hdi_support.h +++ b/uhdf2/include/hdi/hdi_support.h @@ -23,7 +23,7 @@ extern "C" { #endif /* __cplusplus */ void *LoadHdiImpl(const char *desc, const char *serviceName); - +void UnloadHdiImpl(const char *desc, const char *serviceName, void *impl); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/uhdf2/ipc/include/stub_collector.h b/uhdf2/ipc/include/stub_collector.h new file mode 100644 index 0000000000000000000000000000000000000000..46046de2324048cfe5540cc879231a74f6d5e4fd --- /dev/null +++ b/uhdf2/ipc/include/stub_collector.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 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 HDI_STUB_COLLECTOR_H +#define HDI_STUB_COLLECTOR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct StubConstructor { + struct HdfRemoteService **(*constructor)(void *); + void (*destructor)(struct HdfRemoteService **); +}; +void StubConstructorRegister(const char *ifDesc, struct StubConstructor *constructor); +void StubConstructorUnregister(const char *ifDesc, struct StubConstructor *constructor); +struct HdfRemoteService **StubCollectorGetOrNewObject(const char *ifDesc, void *servPtr); +void StubCollectorRemoveObject(const char *ifDesc, void *servPtr); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // HDI_STUB_COLLECTOR_H diff --git a/uhdf2/ipc/src/hdf_sbuf_impl_hipc.cpp b/uhdf2/ipc/src/hdf_sbuf_impl_hipc.cpp index f6d0c06d7a4fbfe3bea0d4e5aad9689a79a477aa..534e70d938575ed80456db028508e6d3d839b26f 100644 --- a/uhdf2/ipc/src/hdf_sbuf_impl_hipc.cpp +++ b/uhdf2/ipc/src/hdf_sbuf_impl_hipc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 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 @@ -330,7 +330,7 @@ static const char16_t *SbufMParcelImplReadString16(struct HdfSBufImpl *sbuf) static int32_t SbufMParcelImplWriteRemoteService(struct HdfSBufImpl *sbuf, const struct HdfRemoteService *service) { if (sbuf == nullptr || service == nullptr) { - return false; + return HDF_ERR_INVALID_PARAM; } MessageParcel *parcel = MParcelCast(sbuf); const struct HdfRemoteServiceHolder *holder = reinterpret_cast(service);