[cj]: 仓颉FFI层接口及其实现.

Change-Id: If393b7b70f1c609d004d823d63e301588ece0bd4
Signed-off-by: liuth <948939870@qq.com>
This commit is contained in:
liuth 2024-10-30 17:23:31 +08:00 committed by liuth
parent a77efbaf08
commit 884f8914ec
10 changed files with 1624 additions and 0 deletions

View File

@ -59,6 +59,7 @@ if (defined(ohos_lite)) {
}
group("device_manager_fwk") {
deps = [
"interfaces/cj:cj_distributed_device_manager_ffi",
"interfaces/inner_kits/native_cpp:devicemanagersdk",
"interfaces/kits:devicemanager_native_js",
]

View File

@ -24,6 +24,7 @@ foundation/distributedhardware/device_manager
│ └── resources # Resource configuration files for PIN display ServiceExtensionAbility
├── figures
├── interfaces
| ├── cj # Cangjie FFI interfaces and their implementation
│ ├── inner_kits # Internal interfaces and their implementation
│ │ └── native_cpp # Internal native interfaces and their implementation
│ │ ├── include

View File

@ -38,6 +38,7 @@ foundation/distributedhardware/distributedhardware_device_manager
│ └── resources # DM PIN码显示ServiceExtensionAbility相关资源配置文件目录
├── figures
├── interfaces
| ├── cj # 仓颉接口ffi层实现存放目录
│ ├── inner_kits # 内部接口及实现存放目录
│ │ └── native_cpp # 内部native接口及实现存放目录
│ │ ├── include

75
interfaces/cj/BUILD.gn Normal file
View File

@ -0,0 +1,75 @@
# 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.
import("//build/ohos.gni")
import("//foundation/distributedhardware/device_manager/device_manager.gni")
ohos_shared_library("cj_distributed_device_manager_ffi") {
branch_protector_ret = "pac_ret"
sanitize = {
boundary_sanitize = true
cfi = true
cfi_cross_dso = true
debug = false
integer_overflow = true
ubsan = true
}
cflags = [
"-fdata-sections",
"-ffunction-sections",
"-fvisibility=hidden",
]
include_dirs = [
"include",
"${common_path}/include",
"${common_path}/include/ipc",
"${innerkits_path}/native_cpp/include",
"${innerkits_path}/native_cpp/include/ipc",
"${innerkits_path}/native_cpp/include/ipc/standard",
]
sources = [
"${common_path}/src/dm_anonymous.cpp",
"${common_path}/src/dm_error_message.cpp",
"src/device_manager_ffi.cpp",
"src/device_manager_impl.cpp",
"src/device_manager_utils.cpp",
]
deps = [ "${innerkits_path}/native_cpp:devicemanagersdk" ]
defines = [
"HI_LOG_ENABLE",
"DH_LOG_TAG=\"cj_distrubuted_devicemanager\"",
"LOG_DOMAIN=0xD004111",
]
external_deps = [
"access_token:libtokenid_sdk",
"bounds_checking_function:libsec_shared",
"bundle_framework:appexecfwk_base",
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_core",
"json:nlohmann_json_static",
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
innerapi_tags = [ "platformsdk" ]
subsystem_name = "distributedhardware"
part_name = "device_manager"
}

View File

@ -0,0 +1,70 @@
/*
* 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 OHOS_DEVICE_MANAGER_FFI_H
#define OHOS_DEVICE_MANAGER_FFI_H
#include "cj_common_ffi.h"
#include "ffi_remote_data.h"
extern "C" {
typedef struct {
char *deviceId;
char *deviceName;
uint16_t deviceType;
char *networkId;
} FfiDeviceBasicInfo;
typedef struct {
FfiDeviceBasicInfo *head;
int64_t size;
} FfiDeviceBasicInfoArray;
FFI_EXPORT int64_t FfiOHOSDistributedDeviceManagerCreateDeviceManager(const char *name, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerReleaseDeviceManager(int64_t id, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerGetAvailableDeviceList(
int64_t id, FfiDeviceBasicInfoArray *deviceInfoList, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerFreeDeviceInfoList(FfiDeviceBasicInfoArray deviceInfoList);
FFI_EXPORT const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceNetworkId(int64_t id, int32_t *errCode);
FFI_EXPORT const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceName(int64_t id, int32_t *errCode);
FFI_EXPORT int32_t FfiOHOSDistributedDeviceManagerGetLocalDeviceType(int64_t id, int32_t *errCode);
FFI_EXPORT const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceId(int64_t id, int32_t *errCode);
FFI_EXPORT const char *FfiOHOSDistributedDeviceManagerGetDeviceName(
int64_t id, const char *networkId, int32_t *errCode);
FFI_EXPORT int32_t FfiOHOSDistributedDeviceManagerGetDeviceType(int64_t id, const char *networkId, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerStartDiscovering(int64_t id, const char *extra, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerStopDiscovering(int64_t id, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerBindTarget(int64_t id, const char *deviceId, const char *bindParam,
bool isMetaType, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerUnbindTarget(int64_t id, const char *deviceId, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerOn(int64_t id, const char *type, void *callback, int32_t *errCode);
FFI_EXPORT void FfiOHOSDistributedDeviceManagerOff(int64_t id, const char *type, int32_t *errCode);
}
#endif // OHOS_DEVICE_MANAGER_FFI_H

View File

@ -0,0 +1,102 @@
/*
* 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 OHOS_DEVICE_MANAGER_IMPL_H
#define OHOS_DEVICE_MANAGER_IMPL_H
#include <condition_variable>
#include <map>
#include <mutex>
#include <string>
#include "ffi_remote_data.h"
#include "device_manager_ffi.h"
#include "device_manager_utils.h"
namespace OHOS {
namespace DistributedHardware {
class DeviceManagerFfiImpl : public OHOS::FFI::FFIData {
public:
explicit DeviceManagerFfiImpl(const std::string &bundleName, int32_t *errCode);
~DeviceManagerFfiImpl() override = default;
static DeviceManagerFfiImpl *GetDeviceManagerFfi(std::string &bundleName);
int32_t ReleaseDeviceManager();
int32_t GetAvailableDeviceList(FfiDeviceBasicInfoArray &deviceInfoList);
static void DeviceListFree(FfiDeviceBasicInfoArray &deviceInfoList, int64_t size = -1);
int32_t GetLocalDeviceNetworkId(const char *&networkId);
int32_t GetLocalDeviceName(const char *&deviceName);
int32_t GetLocalDeviceType(int32_t &deviceType);
int32_t GetLocalDeviceId(const char *&deviceId);
int32_t GetDeviceName(const std::string &networkId, const char *&deviceName);
int32_t GetDeviceType(const std::string &networkId, int32_t &deviceType);
int32_t StartDiscovering(const std::string &extra);
int32_t StopDiscovering();
int32_t BindTarget(const std::string &deviceId, const std::string &bindParam, bool isMetaType);
int32_t UnbindTarget(const std::string &deviceId);
int32_t EventOn(const std::string &type, void *callback);
int32_t EventOff(const std::string &type);
void OnDeviceStatusChange(int32_t action, const DmDeviceBasicInfo &deviceBasicInfo);
void OnDeviceNameChange(const std::string &deviceName);
void OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo);
void OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason);
void OnPublishResult(int32_t publishId, int32_t publishResult);
void OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status, int32_t reason);
void OnDmUiCall(const std::string &paramJson);
private:
void ClearBundleCallbacks();
static int32_t Transform2FfiDeviceBasicInfo(const DmDeviceBasicInfo &in, FfiDeviceBasicInfo &out);
int32_t BindTargetWarpper(const std::string &deviceId,
const std::string &bindParam, std::shared_ptr<DmFfiBindTargetCallback> callback);
int32_t WaitForCallbackCv();
int32_t RegisterDevStatusCallback();
int32_t RegisterDiscoveryCallback();
int32_t RegisterPublishCallback();
int32_t RegisterReplyCallback();
int32_t ReleaseDevStatusCallback();
int32_t ReleaseDiscoveryCallback();
int32_t ReleasePublishCallback();
int32_t ReleaseReplyCallback();
void RegisterCallbackByType(const std::string &type, void *callback);
void Off(const std::string &type);
inline static void FreeDeviceInfo(const FfiDeviceBasicInfo &info)
{
free(info.deviceId);
free(info.deviceName);
free(info.networkId);
};
std::string bundleName_;
std::function<void(int32_t, FfiDeviceBasicInfo *)> deviceStateChangedCallback;
std::function<void(FfiDeviceBasicInfo *)> discoverSuccessCallback;
std::function<void(const char *)> deviceNameChangedCallback;
std::function<void(int32_t)> deviceDiscoverFailedCallback;
std::mutex callbackLock;
std::condition_variable callbackFinishedCv;
std::mutex callbackFinishedMutex;
bool callbackFinished = false;
std::atomic<int32_t> errCode_ = 0;
};
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DEVICE_MANAGER_IMPL_H

View File

@ -0,0 +1,133 @@
/*
* 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 OHOS_DEVICE_MANAGER_UTILS_H
#define OHOS_DEVICE_MANAGER_UTILS_H
#include <atomic>
#include "nlohmann/json.hpp"
#include "device_manager_callback.h"
#include "dm_device_info.h"
namespace OHOS {
namespace DistributedHardware {
enum DmFfiDevStatusChange { UNKNOWN = 0, AVAILABLE = 1, UNAVAILABLE = 2, CHANGE = 3};
class DmFfiInitCallback : public DmInitCallback {
public:
explicit DmFfiInitCallback(const std::string &bundleName) : bundleName_(bundleName)
{
}
~DmFfiInitCallback() override = default;
void OnRemoteDied() override;
private:
std::string bundleName_;
};
class DmFfiDeviceStatusCallback : public DeviceStatusCallback {
public:
explicit DmFfiDeviceStatusCallback(const std::string &bundleName) : bundleName_(bundleName)
{
}
~DmFfiDeviceStatusCallback() override = default;
void OnDeviceOnline(const DmDeviceBasicInfo &deviceBasicInfo) override;
void OnDeviceReady(const DmDeviceBasicInfo &deviceBasicInfo) override;
void OnDeviceOffline(const DmDeviceBasicInfo &deviceBasicInfo) override;
void OnDeviceChanged(const DmDeviceBasicInfo &deviceBasicInfo) override;
private:
std::string bundleName_;
};
class DmFfiDiscoveryCallback : public DiscoveryCallback {
public:
explicit DmFfiDiscoveryCallback(const std::string &bundleName): refCount_(0), bundleName_(bundleName)
{
}
~DmFfiDiscoveryCallback() override = default;
void OnDeviceFound(uint16_t subscribeId,
const OHOS::DistributedHardware::DmDeviceBasicInfo &deviceBasicInfo) override;
void OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason) override;
void OnDiscoverySuccess(uint16_t subscribeId) override;
void IncreaseRefCount();
void DecreaseRefCount();
int32_t GetRefCount();
private:
std::atomic<int32_t> refCount_;
std::string bundleName_;
};
class DmFfiPublishCallback : public PublishCallback {
public:
explicit DmFfiPublishCallback(const std::string &bundleName): refCount_(0), bundleName_(bundleName)
{
}
~DmFfiPublishCallback() override = default;
void OnPublishResult(int32_t publishId, int32_t publishResult) override;
void IncreaseRefCount();
void DecreaseRefCount();
int32_t GetRefCount();
private:
std::atomic<int32_t> refCount_;
std::string bundleName_;
};
class DmFfiDeviceManagerUiCallback : public DeviceManagerUiCallback {
public:
explicit DmFfiDeviceManagerUiCallback(const std::string &bundleName) : bundleName_(bundleName)
{
}
~DmFfiDeviceManagerUiCallback() override = default;
void OnCall(const std::string &paramJson) override;
private:
std::string bundleName_;
};
class DmFfiAuthenticateCallback : public AuthenticateCallback {
public:
explicit DmFfiAuthenticateCallback(const std::string &bundleName) : bundleName_(bundleName)
{
}
~DmFfiAuthenticateCallback() override = default;
void OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status, int32_t reason) override;
private:
std::string bundleName_;
};
class DmFfiBindTargetCallback : public BindTargetCallback {
public:
explicit DmFfiBindTargetCallback(std::string &bundleName) : bundleName_(bundleName)
{
}
~DmFfiBindTargetCallback() override = default;
void OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status, std::string content) override;
private:
std::string bundleName_;
};
const std::string &GetDeviceTypeById(DmDeviceType type);
char *MallocCStr(const char *in);
void InsertMapParames(nlohmann::json &bindParamObj, std::map<std::string, std::string> &bindParamMap);
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DEVICE_MANAGER_IMPL_H

View File

@ -0,0 +1,136 @@
/*
* 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 "device_manager_ffi.h"
#include <string>
#include "device_manager.h"
#include "device_manager_impl.h"
#include "dm_log.h"
int64_t FfiOHOSDistributedDeviceManagerCreateDeviceManager(const char *name, int32_t *errCode)
{
auto deviceManager = OHOS::FFI::FFIData::Create<OHOS::DistributedHardware::DeviceManagerFfiImpl>(
std::string(name), errCode);
if (*errCode != 0) {
LOGE("deviceManager create fail, the errcode is %{public}d", *errCode);
delete static_cast<OHOS::DistributedHardware::DeviceManagerFfiImpl *>(deviceManager);
return 0;
}
return deviceManager->GetID();
}
void FfiOHOSDistributedDeviceManagerReleaseDeviceManager(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->ReleaseDeviceManager();
}
void FfiOHOSDistributedDeviceManagerGetAvailableDeviceList(
int64_t id, FfiDeviceBasicInfoArray *deviceInfoList, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->GetAvailableDeviceList(*deviceInfoList);
}
void FfiOHOSDistributedDeviceManagerFreeDeviceInfoList(FfiDeviceBasicInfoArray deviceInfoList)
{
OHOS::DistributedHardware::DeviceManagerFfiImpl::DeviceListFree(deviceInfoList);
}
const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceNetworkId(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
const char *networkIdPtr = nullptr;
*errCode = instance->GetLocalDeviceNetworkId(networkIdPtr);
return networkIdPtr;
}
const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceName(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
const char *deviceName = nullptr;
*errCode = instance->GetLocalDeviceName(deviceName);
return deviceName;
}
int32_t FfiOHOSDistributedDeviceManagerGetLocalDeviceType(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
int32_t deviceType = 0;
*errCode = instance->GetLocalDeviceType(deviceType);
return deviceType;
}
const char *FfiOHOSDistributedDeviceManagerGetLocalDeviceId(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
const char *deviceId = nullptr;
*errCode = instance->GetLocalDeviceId(deviceId);
return deviceId;
}
const char *FfiOHOSDistributedDeviceManagerGetDeviceName(int64_t id, const char *networkId, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
const char *deviceName = nullptr;
*errCode = instance->GetDeviceName(networkId, deviceName);
return deviceName;
}
int32_t FfiOHOSDistributedDeviceManagerGetDeviceType(int64_t id, const char *networkId, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
int32_t deviceType = 0;
*errCode = instance->GetDeviceType(networkId, deviceType);
return deviceType;
}
void FfiOHOSDistributedDeviceManagerStartDiscovering(int64_t id, const char *extra, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->StartDiscovering(extra);
}
void FfiOHOSDistributedDeviceManagerStopDiscovering(int64_t id, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->StopDiscovering();
}
void FfiOHOSDistributedDeviceManagerBindTarget(
int64_t id, const char *deviceId, const char *bindParam, bool isMetaType, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->BindTarget(deviceId, bindParam, isMetaType);
}
void FfiOHOSDistributedDeviceManagerUnbindTarget(int64_t id, const char *deviceId, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->UnbindTarget(deviceId);
}
void FfiOHOSDistributedDeviceManagerOn(int64_t id, const char *type, void *callback, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->EventOn(type, callback);
}
void FfiOHOSDistributedDeviceManagerOff(int64_t id, const char *type, int32_t *errCode)
{
auto instance = OHOS::FFI::FFIData::GetData<OHOS::DistributedHardware::DeviceManagerFfiImpl>(id);
*errCode = instance->EventOff(type);
}

View File

@ -0,0 +1,881 @@
/*
* 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 "device_manager_impl.h"
#include <memory>
#include <vector>
#include "cj_lambda.h"
#include "ipc_skeleton.h"
#include "device_manager.h"
#include "dm_anonymous.h"
#include "dm_constants.h"
#include "dm_error_message.h"
#include "dm_log.h"
namespace OHOS::DistributedHardware {
namespace {
std::map<std::string, DeviceManagerFfiImpl *> g_deviceManagerMap;
std::map<std::string, std::shared_ptr<DmFfiInitCallback>> g_initCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiDeviceStatusCallback>> g_deviceStatusCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiDiscoveryCallback>> g_DiscoveryCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiPublishCallback>> g_publishCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiAuthenticateCallback>> g_authCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiBindTargetCallback>> g_bindCallbackMap;
std::map<std::string, std::shared_ptr<DmFfiDeviceManagerUiCallback>> g_dmUiCallbackMap;
std::mutex g_deviceManagerMapMutex;
std::mutex g_initCallbackMapMutex;
std::mutex g_deviceStatusCallbackMapMutex;
std::mutex g_discoveryCallbackMapMutex;
std::mutex g_publishCallbackMapMutex;
std::mutex g_authCallbackMapMutex;
std::mutex g_bindCallbackMapMutex;
std::mutex g_dmUiCallbackMapMutex;
const int32_t DM_AUTH_REQUEST_SUCCESS_STATUS = 7;
const int32_t DM_FFI_BUF_LENGTH = 256;
const std::string DM_FFI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange";
const std::string DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS = "discoverSuccess";
const std::string DM_FFI_EVENT_DEVICE_DISCOVER_FAIL = "discoverFailure";
const std::string DM_FFI_EVENT_DEVICE_PUBLISH_SUCCESS = "publishSuccess";
const std::string DM_FFI_EVENT_DEVICE_PUBLISH_FAIL = "publishFailure";
const std::string DEVICE_MANAGER_FFI_CLASS_NAME = "DeviceManager";
const std::string DM_FFI_EVENT_REPLY_RESULT = "replyResult";
const std::string DM_FFI_EVENT_DEVICE_NAME_CHANGE = "deviceNameChange";
enum ErrorCode {
// OK
ERR_OK = 0,
// Permission verify failed.
ERR_NO_PERMISSION = 201,
// The caller is not a system application.
ERR_NOT_SYSTEM_APP = 202,
// Input parameter error.
ERR_INVALID_PARAMS = 401,
// Failed to execute the function.
DM_ERR_FAILED = 11600101,
// Failed to obtain the service.
DM_ERR_OBTAIN_SERVICE = 11600102,
// Authentication invalid.
DM_ERR_AUTHENTICALTION_INVALID = 11600103,
// Discovery invalid.
DM_ERR_DISCOVERY_INVALID = 11600104,
// Publish invalid.
DM_ERR_PUBLISH_INVALID = 11600105,
};
inline int32_t stringCheck(const std::string &str)
{
if (str.size() == 0 || str.size() >= DM_FFI_BUF_LENGTH) {
return ERR_INVALID_PARAMS;
}
return ERR_OK;
}
int32_t transformErrCode(const int32_t errCode)
{
switch (errCode) {
case ERR_DM_NO_PERMISSION:
return ERR_NO_PERMISSION;
case ERR_DM_DISCOVERY_REPEATED:
return DM_ERR_DISCOVERY_INVALID;
case ERR_DM_PUBLISH_REPEATED:
return DM_ERR_PUBLISH_INVALID;
case ERR_DM_AUTH_BUSINESS_BUSY:
return DM_ERR_AUTHENTICALTION_INVALID;
case ERR_DM_INPUT_PARA_INVALID:
case ERR_DM_UNSUPPORTED_AUTH_TYPE:
return ERR_INVALID_PARAMS;
case ERR_DM_INIT_FAILED:
return DM_ERR_OBTAIN_SERVICE;
case ERR_NOT_SYSTEM_APP:
return ERR_NOT_SYSTEM_APP;
default:
return DM_ERR_FAILED;
}
return 0;
}
inline void InsertIntItem(nlohmann::json &jsonObj, std::map<std::string, std::string> &jsonMap,
const std::string &searchKey, const std::string &insertKey)
{
if (IsInt32(jsonObj, searchKey)) {
int32_t value = jsonObj[searchKey].get<int32_t>();
jsonMap.insert(std::pair<std::string, std::string>(insertKey, std::to_string(value)));
}
}
inline void InsertStringItem(nlohmann::json &jsonObj, std::map<std::string, std::string> &jsonMap,
const std::string &searchKey, const std::string &insertKey)
{
if (IsString(jsonObj, searchKey)) {
std::string value = jsonObj[searchKey].get<std::string>();
jsonMap.insert(std::pair<std::string, std::string>(insertKey, value));
}
}
void InsertJsonParamesToMap(nlohmann::json &bindParamObj, std::map<std::string, std::string> &bindParamMap)
{
LOGI("Insert map parames start");
InsertIntItem(bindParamObj, bindParamMap, AUTH_TYPE, PARAM_KEY_AUTH_TYPE);
InsertStringItem(bindParamObj, bindParamMap, APP_OPERATION, PARAM_KEY_APP_OPER);
InsertStringItem(bindParamObj, bindParamMap, CUSTOM_DESCRIPTION, PARAM_KEY_APP_DESC);
InsertStringItem(bindParamObj, bindParamMap, PARAM_KEY_TARGET_PKG_NAME, PARAM_KEY_TARGET_PKG_NAME);
InsertStringItem(bindParamObj, bindParamMap, PARAM_KEY_META_TYPE, PARAM_KEY_META_TYPE);
InsertStringItem(bindParamObj, bindParamMap, PARAM_KEY_PIN_CODE, PARAM_KEY_PIN_CODE);
InsertStringItem(bindParamObj, bindParamMap, PARAM_KEY_AUTH_TOKEN, PARAM_KEY_AUTH_TOKEN);
InsertIntItem(bindParamObj, bindParamMap, BIND_LEVEL, BIND_LEVEL);
}
} // namespace
DeviceManagerFfiImpl::DeviceManagerFfiImpl(const std::string &bundleName, int32_t *errCode) : bundleName_(bundleName)
{
*errCode = stringCheck(bundleName);
if (*errCode != 0) {
LOGE("CreateDeviceManager for bundleName %{public}s failed, ret %{public}d.", bundleName_.c_str(), *errCode);
return;
}
std::shared_ptr<DmFfiInitCallback> initCallback = std::make_shared<DmFfiInitCallback>(bundleName_);
*errCode = DeviceManager::GetInstance().InitDeviceManager(bundleName_, initCallback);
if (*errCode != 0) {
*errCode = transformErrCode(*errCode);
LOGE("CreateDeviceManager for bundleName %{public}s failed, ret %{public}d.", bundleName_.c_str(), *errCode);
return;
}
{
std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
g_initCallbackMap[bundleName_] = initCallback;
}
std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
g_deviceManagerMap[bundleName_] = this;
}
int32_t DeviceManagerFfiImpl::ReleaseDeviceManager()
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
int ret = DeviceManager::GetInstance().UnInitDeviceManager(bundleName_);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("ReleaseDeviceManager for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
ClearBundleCallbacks();
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetAvailableDeviceList(FfiDeviceBasicInfoArray &deviceInfoList)
{
int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
if (ret != 0) {
return transformErrCode(ret);
}
std::vector<DmDeviceBasicInfo> result;
ret = DeviceManager::GetInstance().GetAvailableDeviceList(bundleName_, result);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetTrustedDeviceList for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
if (result.size() == 0) {
return ERR_OK;
}
deviceInfoList.head = static_cast<FfiDeviceBasicInfo *>(malloc(sizeof(FfiDeviceBasicInfo) * result.size()));
if (deviceInfoList.head == nullptr) {
LOGE("Malloc failed");
return DM_ERR_FAILED;
}
deviceInfoList.size = result.size();
for (decltype(result.size()) i = 0; i < result.size(); ++i) {
ret = Transform2FfiDeviceBasicInfo(result[i], deviceInfoList.head[i]);
if (ret != 0) {
DeviceListFree(deviceInfoList, i);
return ret;
}
}
return ERR_OK;
}
void DeviceManagerFfiImpl::DeviceListFree(FfiDeviceBasicInfoArray &deviceInfoList, int64_t size)
{
if (size == -1) {
size = deviceInfoList.size;
}
for (int32_t i = 0; i < size; ++i) {
FreeDeviceInfo(deviceInfoList.head[i]);
}
free(deviceInfoList.head);
deviceInfoList.head = nullptr;
deviceInfoList.size = 0;
}
int32_t DeviceManagerFfiImpl::Transform2FfiDeviceBasicInfo(const DmDeviceBasicInfo &in, FfiDeviceBasicInfo &out)
{
out.deviceId = MallocCStr(in.deviceId);
out.deviceName = MallocCStr(in.deviceName);
out.deviceType = in.deviceTypeId;
out.networkId = MallocCStr(in.networkId);
if (out.deviceId == nullptr || out.deviceName == nullptr || out.networkId == nullptr) {
FreeDeviceInfo(out);
return DM_ERR_FAILED;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetLocalDeviceNetworkId(const char *&networkId)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
std::string result;
int32_t ret = DeviceManager::GetInstance().GetLocalDeviceNetWorkId(bundleName_, result);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetLocalDeviceNetworkId for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetLocalDeviceNetworkId networkId:%{public}s", GetAnonyString(result).c_str());
networkId = MallocCStr(result.c_str());
if (networkId == nullptr) {
return DM_ERR_FAILED;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetLocalDeviceName(const char *&deviceName)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
std::string result;
int32_t ret = DeviceManager::GetInstance().GetLocalDeviceName(bundleName_, result);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetLocalDeviceName for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetLocalDeviceName deviceName:%{public}s", GetAnonyString(result).c_str());
deviceName = MallocCStr(result.c_str());
if (deviceName == nullptr) {
return DM_ERR_FAILED;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetLocalDeviceType(int32_t &deviceType)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
int32_t ret = DeviceManager::GetInstance().GetLocalDeviceType(bundleName_, deviceType);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetLocalDeviceType for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetLocalDeviceType deviceType:%{public}d", deviceType);
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetLocalDeviceId(const char *&deviceId)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
std::string result;
int32_t ret = DeviceManager::GetInstance().GetLocalDeviceId(bundleName_, result);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetLocalDeviceId for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetLocalDeviceId deviceId:%{public}s", GetAnonyString(result).c_str());
deviceId = MallocCStr(result.c_str());
if (deviceId == nullptr) {
return DM_ERR_FAILED;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetDeviceName(const std::string &networkId, const char *&deviceName)
{
int32_t ret = stringCheck(networkId);
if (ret != 0) {
return ret;
}
std::string result;
ret = DeviceManager::GetInstance().GetDeviceName(bundleName_, networkId, result);
LOGI("DeviceManager::GetDeviceName getinstance return.");
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetDeviceName for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetDeviceName deviceName:%{public}s", GetAnonyString(result).c_str());
deviceName = MallocCStr(result.c_str());
if (deviceName == nullptr) {
return DM_ERR_FAILED;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::GetDeviceType(const std::string &networkId, int32_t &deviceType)
{
int32_t ret = stringCheck(networkId);
if (ret != 0) {
return ret;
}
ret = DeviceManager::GetInstance().GetDeviceType(bundleName_, networkId, deviceType);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("GetDeviceType for failed, ret %{public}d", ret);
return ret;
}
LOGI("DeviceManager::GetDeviceType deviceType:%{public}d", deviceType);
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::StartDiscovering(const std::string &extra)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
std::shared_ptr<DmFfiDiscoveryCallback> discoveryCallback = nullptr;
{
std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
auto iter = g_DiscoveryCallbackMap.find(bundleName_);
if (iter == g_DiscoveryCallbackMap.end()) {
discoveryCallback = std::make_shared<DmFfiDiscoveryCallback>(bundleName_);
g_DiscoveryCallbackMap[bundleName_] = discoveryCallback;
} else {
discoveryCallback = iter->second;
}
}
uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
int32_t ret = DeviceManager::GetInstance().StartDeviceDiscovery(bundleName_, tokenId, extra, discoveryCallback);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("Discovery failed, bundleName %{public}s, ret %{public}d", bundleName_.c_str(), ret);
discoveryCallback->OnDiscoveryFailed(static_cast<uint16_t>(0), ret);
return ret;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::StopDiscovering()
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
int32_t ret = DeviceManager::GetInstance().StopDeviceDiscovery(tokenId, bundleName_);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("StopDeviceDiscovery for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::BindTarget(const std::string &deviceId,
const std::string &bindParam, const bool isMetaType)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
int32_t ret = stringCheck(deviceId);
if (ret != 0) {
return ret;
}
callbackFinished = false;
if (isMetaType) {
std::shared_ptr<DmFfiBindTargetCallback> bindTargetCallback = nullptr;
{
std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
auto iter = g_bindCallbackMap.find(bundleName_);
if (iter == g_bindCallbackMap.end()) {
bindTargetCallback = std::make_shared<DmFfiBindTargetCallback>(bundleName_);
g_bindCallbackMap[bundleName_] = bindTargetCallback;
} else {
bindTargetCallback = iter->second;
}
}
int32_t ret = BindTargetWarpper(deviceId, bindParam, bindTargetCallback);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("BindTarget for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
return WaitForCallbackCv();
}
std::shared_ptr<DmFfiAuthenticateCallback> bindDeviceCallback = nullptr;
{
std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
auto iter = g_authCallbackMap.find(bundleName_);
if (iter == g_authCallbackMap.end()) {
bindDeviceCallback = std::make_shared<DmFfiAuthenticateCallback>(bundleName_);
g_authCallbackMap[bundleName_] = bindDeviceCallback;
} else {
bindDeviceCallback = iter->second;
}
}
constexpr int32_t bindType = 1;
ret = DeviceManager::GetInstance().BindDevice(bundleName_, bindType, deviceId, bindParam, bindDeviceCallback);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("BindDevice for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
return WaitForCallbackCv();
}
int32_t DeviceManagerFfiImpl::WaitForCallbackCv()
{
std::unique_lock<std::mutex> autoLock(callbackFinishedMutex);
callbackFinishedCv.wait(autoLock, [this] { return this->callbackFinished; });
LOGI("WaitForCallbackCv got notified, errCode is %{public}d", errCode_.load());
return errCode_.load();
}
int32_t DeviceManagerFfiImpl::UnbindTarget(const std::string &deviceId)
{
if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) {
return ERR_NO_PERMISSION;
}
int32_t ret = stringCheck(deviceId);
if (ret != 0) {
return ret;
}
LOGI("UnBindDevice deviceId = %{public}s", GetAnonyString(deviceId).c_str());
ret = DeviceManager::GetInstance().UnBindDevice(bundleName_, deviceId);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("UnBindDevice for bundleName %{public}s failed, ret %{public}d", bundleName_.c_str(), ret);
return ret;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::EventOn(const std::string &type, void *callback)
{
int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
if (ret != 0) {
return transformErrCode(ret);
}
LOGI("EventOn for bundleName %{public}s, eventType %{public}s ", bundleName_.c_str(), type.c_str());
RegisterCallbackByType(type, callback);
if (type == DM_FFI_EVENT_DEVICE_STATE_CHANGE || type == DM_FFI_EVENT_DEVICE_NAME_CHANGE) {
return RegisterDevStatusCallback();
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS || type == DM_FFI_EVENT_DEVICE_DISCOVER_FAIL) {
return RegisterDiscoveryCallback();
}
return ERR_INVALID_PARAMS;
}
int32_t DeviceManagerFfiImpl::EventOff(const std::string &type)
{
int32_t ret = DeviceManager::GetInstance().CheckNewAPIAccessPermission();
if (ret != 0) {
return ret;
}
LOGI("EventOff for bundleName %{public}s, eventType %{public}s ", bundleName_.c_str(), type.c_str());
Off(type);
if (type == DM_FFI_EVENT_DEVICE_STATE_CHANGE || type == DM_FFI_EVENT_DEVICE_NAME_CHANGE) {
if (!deviceStateChangedCallback && !deviceNameChangedCallback) {
return ReleaseDevStatusCallback();
}
return ERR_OK;
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS || type == DM_FFI_EVENT_DEVICE_DISCOVER_FAIL) {
return ReleaseDiscoveryCallback();
}
return ERR_INVALID_PARAMS;
}
void DeviceManagerFfiImpl::OnDeviceStatusChange(int32_t action, const DmDeviceBasicInfo &deviceBasicInfo)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
if (deviceStateChangedCallback) {
auto ptr = static_cast<FfiDeviceBasicInfo *>(malloc(sizeof(FfiDeviceBasicInfo)));
if (ptr == nullptr) {
LOGE("OnDeviceStatusChange malloc FfiDeviceBasicInfo failed.");
return;
}
int32_t ret = Transform2FfiDeviceBasicInfo(deviceBasicInfo, *ptr);
if (ret != 0) {
LOGE("OnDeviceStatusChange failed to transform DmDeviceBasicInfo.");
return;
}
deviceStateChangedCallback(action, ptr);
FreeDeviceInfo(*ptr);
free(ptr);
}
}
void DeviceManagerFfiImpl::OnDeviceNameChange(const std::string &deviceName)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
if (deviceNameChangedCallback) {
char *cDeviceName = MallocCStr(deviceName.c_str());
if (cDeviceName == nullptr) {
LOGE("OnDeviceNameChange malloc deviname failed.");
return;
}
deviceNameChangedCallback(cDeviceName);
free(cDeviceName);
}
}
void DeviceManagerFfiImpl::OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
if (discoverSuccessCallback) {
auto ptr = static_cast<FfiDeviceBasicInfo *>(malloc(sizeof(FfiDeviceBasicInfo)));
if (ptr == nullptr) {
LOGE("OnDeviceStatusChange malloc FfiDeviceBasicInfo failed.");
return;
}
int32_t ret = Transform2FfiDeviceBasicInfo(deviceBasicInfo, *ptr);
if (ret != 0) {
LOGE("OnDeviceStatusChange failed to transform DmDeviceBasicInfo.");
return;
}
discoverSuccessCallback(ptr);
FreeDeviceInfo(*ptr);
free(ptr);
}
}
void DeviceManagerFfiImpl::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
LOGI("OnDiscoveryFailed for subscribeId %{public}d", (int32_t)subscribeId);
if (deviceDiscoverFailedCallback) {
deviceDiscoverFailedCallback(failedReason);
}
}
void DeviceManagerFfiImpl::OnPublishResult(int32_t publishId, int32_t publishResult)
{
LOGI("OnPublishResult for publishId %{public}d, publishResult %{public}d", publishId, publishResult);
}
void DeviceManagerFfiImpl::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
int32_t reason)
{
LOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason);
if (reason == DM_OK && (status <= STATUS_DM_CLOSE_PIN_INPUT_UI && status >= STATUS_DM_SHOW_AUTHORIZE_UI)) {
LOGI("update ui change, status: %{public}d, reason: %{public}d", status, reason);
return;
}
if (status == DM_AUTH_REQUEST_SUCCESS_STATUS && reason == 0) {
LOGI("OnAuthResult success");
errCode_ = ERR_OK;
} else {
LOGI("OnAuthResult failed");
errCode_ = reason;
}
std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
g_authCallbackMap.erase(bundleName_);
callbackFinished = true;
callbackFinishedCv.notify_one();
}
void DeviceManagerFfiImpl::OnDmUiCall(const std::string &paramJson)
{
LOGI("OnCall for paramJson");
}
DeviceManagerFfiImpl *DeviceManagerFfiImpl::GetDeviceManagerFfi(std::string &bundleName)
{
std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
auto iter = g_deviceManagerMap.find(bundleName);
if (iter == g_deviceManagerMap.end()) {
return nullptr;
}
return iter->second;
}
void DeviceManagerFfiImpl::ClearBundleCallbacks()
{
LOGI("ClearBundleCallbacks start for bundleName %{public}s", bundleName_.c_str());
{
std::lock_guard<std::mutex> autoLock(g_deviceManagerMapMutex);
g_deviceManagerMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_initCallbackMapMutex);
g_initCallbackMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
g_deviceStatusCallbackMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
g_DiscoveryCallbackMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
g_publishCallbackMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_authCallbackMapMutex);
g_authCallbackMap.erase(bundleName_);
}
{
std::lock_guard<std::mutex> autoLock(g_bindCallbackMapMutex);
g_bindCallbackMap.erase(bundleName_);
}
return;
}
int32_t DeviceManagerFfiImpl::BindTargetWarpper(const std::string &deviceId,
const std::string &bindParam, std::shared_ptr<DmFfiBindTargetCallback> callback)
{
if (bindParam.empty()) {
return ERR_INVALID_PARAMS;
}
nlohmann::json bindParamObj = nlohmann::json::parse(bindParam, nullptr, false);
if (bindParamObj.is_discarded()) {
return ERR_INVALID_PARAMS;
}
PeerTargetId targetId;
targetId.deviceId = deviceId;
if (IsString(bindParamObj, PARAM_KEY_BR_MAC)) {
targetId.brMac = bindParamObj[PARAM_KEY_BR_MAC].get<std::string>();
}
if (IsString(bindParamObj, PARAM_KEY_BLE_MAC)) {
targetId.bleMac = bindParamObj[PARAM_KEY_BLE_MAC].get<std::string>();
}
if (IsString(bindParamObj, PARAM_KEY_WIFI_IP)) {
targetId.wifiIp = bindParamObj[PARAM_KEY_WIFI_IP].get<std::string>();
}
if (IsInt32(bindParamObj, PARAM_KEY_WIFI_PORT)) {
targetId.wifiPort = (uint16_t)(bindParamObj[PARAM_KEY_WIFI_PORT].get<int32_t>());
}
std::map<std::string, std::string> bindParamMap;
InsertJsonParamesToMap(bindParamObj, bindParamMap);
return DeviceManager::GetInstance().BindTarget(bundleName_, targetId, bindParamMap, callback);
}
int32_t DeviceManagerFfiImpl::RegisterDevStatusCallback()
{
LOGI("RegisterDevStatusCallback start for bundleName %{public}s", bundleName_.c_str());
{
std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
if (g_deviceStatusCallbackMap.find(bundleName_) != g_deviceStatusCallbackMap.end()) {
LOGI("bundleName already register.");
return ERR_OK;
}
}
auto callback = std::make_shared<DmFfiDeviceStatusCallback>(bundleName_);
int32_t ret = DeviceManager::GetInstance().RegisterDevStatusCallback(bundleName_, "", callback);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("RegisterDevStatusCallback failed for bundleName %{public}s", bundleName_.c_str());
return ret;
}
{
std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
g_deviceStatusCallbackMap[bundleName_] = callback;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::RegisterDiscoveryCallback()
{
auto discoveryCallback = std::make_shared<DmFfiDiscoveryCallback>(bundleName_);
{
std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
g_DiscoveryCallbackMap[bundleName_] = discoveryCallback;
}
discoveryCallback->IncreaseRefCount();
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::RegisterPublishCallback()
{
auto publishCallback = std::make_shared<DmFfiPublishCallback>(bundleName_);
{
std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
g_publishCallbackMap[bundleName_] = publishCallback;
}
publishCallback->IncreaseRefCount();
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::RegisterReplyCallback()
{
auto dmUiCallback = std::make_shared<DmFfiDeviceManagerUiCallback>(bundleName_);
int32_t ret = DeviceManager::GetInstance().RegisterDeviceManagerFaCallback(bundleName_, dmUiCallback);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("RegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName_.c_str());
return ret;
}
{
std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
g_dmUiCallbackMap[bundleName_] = dmUiCallback;
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::ReleaseDevStatusCallback()
{
{
std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
auto iter = g_deviceStatusCallbackMap.find(bundleName_);
if (iter == g_deviceStatusCallbackMap.end()) {
LOGE("ReleaseDmCallback: cannot find statusCallback for bundleName %{public}s", bundleName_.c_str());
return ERR_INVALID_PARAMS;
}
}
int32_t ret = DeviceManager::GetInstance().UnRegisterDevStatusCallback(bundleName_);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("UnRegisterDevStatusCallback failed for bundleName %{public}s", bundleName_.c_str());
return ret;
}
{
std::lock_guard<std::mutex> autoLock(g_deviceStatusCallbackMapMutex);
g_deviceStatusCallbackMap.erase(bundleName_);
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::ReleaseDiscoveryCallback()
{
LOGI("ReleaseDiscoveryCallback for bundleName %{public}s", bundleName_.c_str());
std::shared_ptr<DmFfiDiscoveryCallback> DiscoveryCallback = nullptr;
{
std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
auto iter = g_DiscoveryCallbackMap.find(bundleName_);
if (iter == g_DiscoveryCallbackMap.end()) {
return ERR_OK;
}
DiscoveryCallback = iter->second;
}
DiscoveryCallback->DecreaseRefCount();
if (DiscoveryCallback->GetRefCount() == 0) {
std::lock_guard<std::mutex> autoLock(g_discoveryCallbackMapMutex);
g_DiscoveryCallbackMap.erase(bundleName_);
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::ReleasePublishCallback()
{
LOGI("ReleasePublishCallback for bundleName %{public}s", bundleName_.c_str());
std::shared_ptr<DmFfiPublishCallback> publishCallback = nullptr;
{
std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
auto iter = g_publishCallbackMap.find(bundleName_);
if (iter == g_publishCallbackMap.end()) {
return ERR_OK;
}
publishCallback = iter->second;
}
publishCallback->DecreaseRefCount();
if (publishCallback->GetRefCount() == 0) {
std::lock_guard<std::mutex> autoLock(g_publishCallbackMapMutex);
g_publishCallbackMap.erase(bundleName_);
}
return ERR_OK;
}
int32_t DeviceManagerFfiImpl::ReleaseReplyCallback()
{
{
std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
auto iter = g_dmUiCallbackMap.find(bundleName_);
if (iter == g_dmUiCallbackMap.end()) {
LOGE("cannot find dmFaCallback for bundleName %{public}s", bundleName_.c_str());
return ERR_INVALID_PARAMS;
}
}
int32_t ret = DeviceManager::GetInstance().UnRegisterDeviceManagerFaCallback(bundleName_);
if (ret != 0) {
ret = transformErrCode(ret);
LOGE("UnRegisterDeviceManagerFaCallback failed for bundleName %{public}s", bundleName_.c_str());
return ret;
}
{
std::lock_guard<std::mutex> autoLock(g_dmUiCallbackMapMutex);
g_dmUiCallbackMap.erase(bundleName_);
}
return ERR_OK;
}
void DeviceManagerFfiImpl::RegisterCallbackByType(const std::string &type, void *callback)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
if (type == DM_FFI_EVENT_DEVICE_STATE_CHANGE) {
deviceStateChangedCallback = CJLambda::Create(
reinterpret_cast<void (*)(int32_t, FfiDeviceBasicInfo *)>(callback));
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS) {
discoverSuccessCallback = CJLambda::Create(reinterpret_cast<void (*)(FfiDeviceBasicInfo *)>(callback));
} else if (type == DM_FFI_EVENT_DEVICE_NAME_CHANGE) {
deviceNameChangedCallback = CJLambda::Create(reinterpret_cast<void (*)(const char *)>(callback));
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_FAIL) {
deviceDiscoverFailedCallback = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
} else {
LOGE("RegisterCallbackByType call with wrong type.");
}
}
void DeviceManagerFfiImpl::Off(const std::string &type)
{
std::lock_guard<std::mutex> autoLock(callbackLock);
if (type == DM_FFI_EVENT_DEVICE_STATE_CHANGE) {
deviceStateChangedCallback = nullptr;
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS) {
discoverSuccessCallback = nullptr;
} else if (type == DM_FFI_EVENT_DEVICE_NAME_CHANGE) {
deviceNameChangedCallback = nullptr;
} else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_FAIL) {
deviceDiscoverFailedCallback = nullptr;
} else {
LOGE("Off call with wrong type.");
}
}
} // namespace OHOS::DistributedHardware

View File

@ -0,0 +1,224 @@
/*
* 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 "device_manager_utils.h"
#include <string>
#include <map>
#include <mutex>
#include "device_manager_impl.h"
#include "dm_anonymous.h"
#include "dm_constants.h"
#include "dm_log.h"
namespace OHOS::DistributedHardware {
namespace {
constexpr std::size_t MAX_MALLOC_SIZE = 0x10000;
}
void DmFfiInitCallback::OnRemoteDied()
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnRemoteDied, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
}
LOGI("OnRemoteDied, deviceManagerFfi bundleName %{public}s", bundleName_.c_str());
}
void DmFfiDeviceStatusCallback::OnDeviceOnline(const DmDeviceBasicInfo &deviceBasicInfo)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDeviceOnline, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDeviceStatusChange(DmFfiDevStatusChange::UNKNOWN, deviceBasicInfo);
}
}
void DmFfiDeviceStatusCallback::OnDeviceReady(const DmDeviceBasicInfo &deviceBasicInfo)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDeviceReady, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDeviceStatusChange(DmFfiDevStatusChange::AVAILABLE, deviceBasicInfo);
}
}
void DmFfiDeviceStatusCallback::OnDeviceOffline(const DmDeviceBasicInfo &deviceBasicInfo)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDeviceOffline, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDeviceStatusChange(DmFfiDevStatusChange::UNAVAILABLE, deviceBasicInfo);
}
}
void DmFfiDeviceStatusCallback::OnDeviceChanged(const DmDeviceBasicInfo &deviceBasicInfo)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDeviceChanged, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDeviceNameChange(deviceBasicInfo.deviceName);
}
}
void DmFfiDiscoveryCallback::OnDeviceFound(uint16_t subscribeId, const DmDeviceBasicInfo &deviceBasicInfo)
{
LOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDeviceFound, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDeviceFound(subscribeId, deviceBasicInfo);
}
}
void DmFfiDiscoveryCallback::OnDiscoveryFailed(uint16_t subscribeId, int32_t failedReason)
{
LOGI("OnDiscoveryFailed for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDiscoveryFailed, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDiscoveryFailed(subscribeId, failedReason);
}
}
void DmFfiDiscoveryCallback::OnDiscoverySuccess(uint16_t subscribeId)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnDiscoverySuccess, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
return;
}
LOGI("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId);
}
void DmFfiDiscoveryCallback::IncreaseRefCount()
{
refCount_++;
}
void DmFfiDiscoveryCallback::DecreaseRefCount()
{
refCount_--;
}
int32_t DmFfiDiscoveryCallback::GetRefCount()
{
return refCount_;
}
void DmFfiPublishCallback::OnPublishResult(int32_t publishId, int32_t publishResult)
{
LOGI("OnPublishResult for %{public}s, publishId %{public}d, publishResult %{public}d", bundleName_.c_str(),
publishId, publishResult);
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnPublishResult, deviceManagerFfi failed for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnPublishResult(publishId, publishResult);
}
}
void DmFfiPublishCallback::IncreaseRefCount()
{
refCount_++;
}
void DmFfiPublishCallback::DecreaseRefCount()
{
refCount_--;
}
int32_t DmFfiPublishCallback::GetRefCount()
{
return refCount_;
}
void DmFfiAuthenticateCallback::OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status,
int32_t reason)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnAuthResult, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnAuthResult(deviceId, token, status, reason);
}
}
void DmFfiDeviceManagerUiCallback::OnCall(const std::string &paramJson)
{
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnCall, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnDmUiCall(paramJson);
}
}
void DmFfiBindTargetCallback::OnBindResult(const PeerTargetId &targetId, int32_t result, int32_t status,
std::string content)
{
(void)targetId;
DeviceManagerFfiImpl *deviceManagerFfi = DeviceManagerFfiImpl::GetDeviceManagerFfi(bundleName_);
if (deviceManagerFfi == nullptr) {
LOGE("OnBindResult, deviceManagerFfi not find for bundleName %{public}s", bundleName_.c_str());
} else {
deviceManagerFfi->OnAuthResult(content, "", status, result);
}
}
const std::string &GetDeviceTypeById(DmDeviceType type)
{
const static std::pair<const DmDeviceType, const std::string &> mapArray[] = {
{DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_UNKNOWN_STRING},
{DEVICE_TYPE_PHONE, DEVICE_TYPE_PHONE_STRING},
{DEVICE_TYPE_PAD, DEVICE_TYPE_PAD_STRING},
{DEVICE_TYPE_TV, DEVICE_TYPE_TV_STRING},
{DEVICE_TYPE_CAR, DEVICE_TYPE_CAR_STRING},
{DEVICE_TYPE_WATCH, DEVICE_TYPE_WATCH_STRING},
{DEVICE_TYPE_WIFI_CAMERA, DEVICE_TYPE_WIFICAMERA_STRING},
{DEVICE_TYPE_PC, DEVICE_TYPE_PC_STRING},
{DEVICE_TYPE_SMART_DISPLAY, DEVICE_TYPE_SMART_DISPLAY_STRING},
{DEVICE_TYPE_2IN1, DEVICE_TYPE_2IN1_STRING},
};
for (const auto& item : mapArray) {
if (item.first == type) {
return item.second;
}
}
return DEVICE_TYPE_UNKNOWN_STRING;
}
char *MallocCStr(const char *in)
{
std::size_t len = strlen(in);
if (len >= MAX_MALLOC_SIZE) {
return nullptr;
}
char *result = static_cast<char *>(malloc(len + 1));
if (result == nullptr) {
LOGE("Malloc failed.");
return nullptr;
}
std::char_traits<char>::copy(result, in, len+1);
return result;
}
} // OHOS::DistributedHardware