!561 feat:support hdi passthrought mode

Merge pull request !561 from yue/master
This commit is contained in:
openharmony_ci
2022-05-06 03:14:33 +00:00
committed by Gitee
3 changed files with 76 additions and 26 deletions
+6 -6
View File
@@ -50,9 +50,7 @@ template("hdi") {
config("hdi_public_config") {
include_dirs = [
"$hdf_uhdf_path/include/hdi",
"$hdf_uhdf_path/include/host",
"$hdf_uhdf_path/ipc/include",
"${files_info.root_package_dir}",
"${files_info.version_dir}",
]
@@ -121,9 +119,10 @@ template("hdi") {
public_configs = [ ":hdi_public_config" ]
deps = [
deps = [ "$hdi_gen" ]
public_deps = [
"$hdf_uhdf_path/hdi:libhdi",
"$hdi_gen",
"//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter",
"//drivers/adapter/uhdf2/utils:libhdf_utils",
]
@@ -164,9 +163,10 @@ template("hdi") {
public_configs = [ ":hdi_public_config" ]
deps = [
deps = [ "$hdi_gen" ]
public_deps = [
"$hdf_uhdf_path/hdi:libhdi",
"$hdi_gen",
"//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter",
"//drivers/adapter/uhdf2/utils:libhdf_utils",
]
+58 -17
View File
@@ -15,6 +15,7 @@
#include "hdi_support.h"
#include <dlfcn.h>
#include <regex>
#include <securec.h>
#include <string>
#include <string_ex.h>
@@ -33,37 +34,76 @@
#endif
namespace {
constexpr int VERSION_SIZE = 2;
constexpr size_t INTERFACE_SIZE = 5;
constexpr size_t INTERFACE_VERSION_INDEX = 3;
constexpr size_t INTERFACE_NAME_INDEX = 2;
constexpr size_t INTERFACE_MATCH_RESIZE = 4;
constexpr size_t INTERFACE_VERSION_MAJOR_INDEX = 1;
constexpr size_t INTERFACE_VERSION_MINOR_INDEX = 2;
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_]*)");
} // namespace
static int ParseInterface(
const std::string &fullName, std::string &interface, uint32_t &versionMajor, uint32_t &versionMinor)
static int32_t ParseInterface(const std::string &fullName, std::string &interface, uint32_t &versionMajor,
uint32_t &versionMinor)
{
std::vector<std::string> spInfo;
OHOS::SplitStr(fullName, ".", spInfo, false, true);
if (spInfo.size() != INTERFACE_SIZE) {
HDF_LOGE("invlid interface format");
std::smatch result;
if (!std::regex_match(fullName, result, reInfDesc)) {
HDF_LOGE("invalid format of interface descriptor '%{public}s'", fullName.c_str());
return HDF_FAILURE;
}
interface = spInfo[INTERFACE_NAME_INDEX];
int ret = sscanf_s(spInfo[INTERFACE_VERSION_INDEX].data(), "V%u_%u", &versionMajor, &versionMinor);
if (ret != VERSION_SIZE) {
HDF_LOGE("failed to get interface version\n");
if (result.size() < INTERFACE_MATCH_RESIZE) {
HDF_LOGE("failed to parse interface descriptor '%{public}s'", fullName.c_str());
return HDF_FAILURE;
}
versionMajor = std::stoul(result[INTERFACE_VERSION_MAJOR_INDEX]);
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()) {
HDF_LOGE("failed to get invalid interface name");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
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;
}
/*
* interface descriptor name: ohos.hdi.sample.v1_0.IFoo
* interface: Foo
* versionMajor: 1
* versionMinor: 0
* library name: libfoo_service_1.0.z.so
* method name: FooImplGetInstance
*/
void *LoadHdiImpl(const char *fullIfName)
{
char path[PATH_MAX + 1] = {0};
char resolvedPath[PATH_MAX + 1] = {0};
// interface name like "OHOS.HDI.Sample.V1_0.IFoo", the last two are version and interface name
// interface descriptor name like "ohos.hdi.sample.v1_0.IFoo", the last two are version and interface base name
if (fullIfName == nullptr) {
HDF_LOGE("fullIfName is nullptr");
return nullptr;
@@ -78,9 +118,10 @@ void *LoadHdiImpl(const char *fullIfName)
HDF_LOGE("failed to parse hdi interface info");
return nullptr;
}
// hdi implement name like libsample_service_1.0.z.so
// hdi implement name like libfoo_service_1.0.z.so
if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/lib%s_service_%u.%u.z.so", HDI_SO_PATH,
OHOS::LowerStr(interfaceName).data(), versionMajor, versionMinor) < 0) {
TransFileName(interfaceName).data(), versionMajor, versionMinor) < 0) {
HDF_LOGE("%{public}s snprintf_s failed", __func__);
return nullptr;
}
+12 -3
View File
@@ -18,6 +18,7 @@
#include "hdf_base.h"
#include "hdf_log.h"
#include "osal_time.h"
using namespace OHOS::HDI;
@@ -67,15 +68,23 @@ OHOS::sptr<OHOS::IRemoteObject> ObjectCollector::NewObject(
OHOS::sptr<OHOS::IRemoteObject> ObjectCollector::GetOrNewObject(
const OHOS::sptr<HdiBase> &interface, const std::u16string &interfaceName)
{
std::lock_guard<std::mutex> lock(mutex_);
mutex_.lock();
RETRY:
auto it = interfaceObjectCollector_.find(interface.GetRefPtr());
if (it != interfaceObjectCollector_.end()) {
if (it->second->GetSptrRefCount() == 0) {
// may object is releasing, yield to sync
mutex_.unlock();
OsalMSleep(1);
mutex_.lock();
goto RETRY;
}
mutex_.unlock();
return it->second;
}
sptr<IRemoteObject> object = NewObjectLocked(interface, interfaceName);
interfaceObjectCollector_[interface.GetRefPtr()] = object.GetRefPtr();
mutex_.unlock();
return object;
}