diff --git a/BUILD.gn b/BUILD.gn index 71aed68449e47af4cf6194b7532a0c41993ef8a9..d7f8932acbafd6f409ddd68fb61da7380968a4a1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -61,6 +61,7 @@ if (defined(ohos_lite)) { deps = [ "interfaces/inner_kits/native_cpp:devicemanagersdk", "interfaces/kits:devicemanager_native_js", + "interfaces/cj:cj_distributed_device_manager_ffi", ] } group("device_manager_test") { diff --git a/README.md b/README.md index e5359e382e2ccd0fde4c729a8105a4138c2d35f9..db56f0a4849aa8e27538e6081e27ac4627491ffe 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/README_zh.md b/README_zh.md index a69927fa1549fe0287f01e51ee1dde9824c37e52..33fd30bc971bac08a4a09c13c2df86cfe0aefeb1 100644 --- a/README_zh.md +++ b/README_zh.md @@ -38,6 +38,7 @@ foundation/distributedhardware/distributedhardware_device_manager │ └── resources # DM PIN码显示ServiceExtensionAbility相关资源配置文件目录 ├── figures ├── interfaces +| ├── cj # 仓颉接口ffi层实现存放目录 │ ├── inner_kits # 内部接口及实现存放目录 │ │ └── native_cpp # 内部native接口及实现存放目录 │ │ ├── include diff --git a/interfaces/cj/BUILD.gn b/interfaces/cj/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4835a76ff8c484b38ec28c5cec066cc3f7f92201 --- /dev/null +++ b/interfaces/cj/BUILD.gn @@ -0,0 +1,75 @@ +# Copyright (c) 2022-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_native", + "napi:cj_bind_ffi", + ] + + innerapi_tags = ["platformsdk"] + subsystem_name = "distributedhardware" + part_name = "device_manager" +} diff --git a/interfaces/cj/include/device_manager_ffi.h b/interfaces/cj/include/device_manager_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..7ff264a2646434ae488ef09644930f927a0ba3b0 --- /dev/null +++ b/interfaces/cj/include/device_manager_ffi.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2023 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 FfiCreateDeviceManager(const char *name, int32_t *errCode); + +FFI_EXPORT void FfiReleaseDeviceManager(int64_t id, int32_t *errCode); + +FFI_EXPORT void FfiGetAvailableDeviceList(int64_t id, FfiDeviceBasicInfoArray *deviceInfoList, int32_t *errCode); + +FFI_EXPORT void FfiFreeDeviceInfoList(FfiDeviceBasicInfoArray deviceInfoList); + +FFI_EXPORT const char *FfiGetLocalDeviceNetworkId(int64_t id, int32_t *errCode); + +FFI_EXPORT const char *FfiGetLocalDeviceName(int64_t id, int32_t *errCode); + +FFI_EXPORT int32_t FfiGetLocalDeviceType(int64_t id, int32_t *errCode); + +FFI_EXPORT const char *FfiGetLocalDeviceId(int64_t id, int32_t *errCode); + +FFI_EXPORT const char *FfiGetDeviceName(int64_t id, const char *networkId, int32_t *errCode); + +FFI_EXPORT int32_t FfiGetDeviceType(int64_t id, const char *networkId, int32_t *errCode); + +FFI_EXPORT void FfiStartDiscovering(int64_t id, const char *extra, int32_t *errCode); + +FFI_EXPORT void FfiStopDiscovering(int64_t id, int32_t *errCode); + +FFI_EXPORT void FfiBindTarget(int64_t id, const char *deviceId, const char *bindParam, + bool isMetaType, int32_t *errCode); + +FFI_EXPORT void FfiUnbindTarget(int64_t id, const char *deviceId, int32_t *errCode); + +FFI_EXPORT void FfiOn(int64_t id, const char *type, void *callback, int32_t *errCode); + +FFI_EXPORT void FfiOff(int64_t id, const char *type, int32_t *errCode); + +} + +#endif // OHOS_DEVICE_MANAGER_FFI_H diff --git a/interfaces/cj/include/device_manager_impl.h b/interfaces/cj/include/device_manager_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..cf58c0ac49ba7ecca3675ed5b25bf03e2402ca9c --- /dev/null +++ b/interfaces/cj/include/device_manager_impl.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022-2023 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 "device_manager_utils.h" +#include "device_manager_ffi.h" + +#include +#include +#include +#include + +#include "ffi_remote_data.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 ¶mJson); + +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 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 deviceStateChangedCallback; + std::function discoverSuccessCallback; + std::function deviceNameChangedCallback; + std::function deviceDiscoverFailedCallback; + std::mutex callbackLock; + + std::condition_variable callbackFinishedCv; + std::mutex callbackFinishedMutex; + bool callbackFinished = false; + std::atomic errCode_; +}; + + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_IMPL_H diff --git a/interfaces/cj/include/device_manager_utils.h b/interfaces/cj/include/device_manager_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..f5bc4e888f5cf65ba73e6484fc6cef71e33f09c6 --- /dev/null +++ b/interfaces/cj/include/device_manager_utils.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022-2023 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 + +#include "device_manager_callback.h" +#include "dm_device_info.h" +#include "nlohmann/json.hpp" + +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 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 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 ¶mJson) 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 &bindParamMap); + +} // namespace DistributedHardware +} // namespace OHOS + +#endif // OHOS_DEVICE_MANAGER_IMPL_H diff --git a/interfaces/cj/src/device_manager_ffi.cpp b/interfaces/cj/src/device_manager_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e9ccda0c9337e5125ad376aedf0f68907fe7d3f9 --- /dev/null +++ b/interfaces/cj/src/device_manager_ffi.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2022-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 "device_manager_impl.h" + +#include + +#include "device_manager.h" +#include "dm_log.h" + + +int64_t FfiCreateDeviceManager(const char *name, int32_t *errCode) +{ + auto deviceManager = OHOS::FFI::FFIData::Create( + std::string(name), errCode); + if (*errCode != 0) { + LOGE("deviceManager create fail, the errcode is %{public}d", *errCode); + delete static_cast(deviceManager); + return 0; + } + LOGI("deviceManager create successed, the ID is %{public}ld", deviceManager->GetID()); + return deviceManager->GetID(); +} + +void FfiReleaseDeviceManager(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->ReleaseDeviceManager(); +} + +void FfiGetAvailableDeviceList(int64_t id, FfiDeviceBasicInfoArray *deviceInfoList, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->GetAvailableDeviceList(*deviceInfoList); +} + +void FfiFreeDeviceInfoList(FfiDeviceBasicInfoArray deviceInfoList) +{ + OHOS::DistributedHardware::DeviceManagerFfiImpl::DeviceListFree(deviceInfoList); +} + +const char *FfiGetLocalDeviceNetworkId(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + const char *networkIdPtr = nullptr; + *errCode = instance->GetLocalDeviceNetworkId(networkIdPtr); + return networkIdPtr; +} + +const char *FfiGetLocalDeviceName(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + const char *deviceName = nullptr; + *errCode = instance->GetLocalDeviceName(deviceName); + return deviceName; +} + +int32_t FfiGetLocalDeviceType(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + int32_t deviceType = 0; + *errCode = instance->GetLocalDeviceType(deviceType); + return deviceType; +} + +const char *FfiGetLocalDeviceId(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + const char *deviceId = nullptr; + *errCode = instance->GetLocalDeviceId(deviceId); + return deviceId; +} + +const char *FfiGetDeviceName(int64_t id, const char *networkId, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + const char *deviceName = nullptr; + *errCode = instance->GetDeviceName(networkId, deviceName); + return deviceName; +} + +int32_t FfiGetDeviceType(int64_t id, const char *networkId, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + int32_t deviceType = 0; + *errCode = instance->GetDeviceType(networkId, deviceType); + return deviceType; +} + +void FfiStartDiscovering(int64_t id, const char *extra, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->StartDiscovering(extra); +} + +void FfiStopDiscovering(int64_t id, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->StopDiscovering(); +} + +void FfiBindTarget(int64_t id, const char *deviceId, const char *bindParam, bool isMetaType, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->BindTarget(deviceId, bindParam, isMetaType); +} + +void FfiUnbindTarget(int64_t id, const char *deviceId, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->UnbindTarget(deviceId); +} + +void FfiOn(int64_t id, const char *type, void *callback, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->EventOn(type, callback); +} + +void FfiOff(int64_t id, const char *type, int32_t *errCode) +{ + auto instance = OHOS::FFI::FFIData::GetData(id); + *errCode = instance->EventOff(type); +} diff --git a/interfaces/cj/src/device_manager_impl.cpp b/interfaces/cj/src/device_manager_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4038b21201a04ce8d8b928cc5fe1d08e2760c134 --- /dev/null +++ b/interfaces/cj/src/device_manager_impl.cpp @@ -0,0 +1,847 @@ +/* + * Copyright (c) 2022-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 +#include + +#include "dm_log.h" +#include "device_manager.h" +#include "dm_anonymous.h" +#include "ipc_skeleton.h" +#include "dm_error_message.h" +#include "dm_constants.h" +#include "cj_lambda.h" + +namespace OHOS::DistributedHardware { + +namespace { +std::map g_deviceManagerMap; +std::map> g_initCallbackMap; +std::map> g_deviceStatusCallbackMap; +std::map> g_DiscoveryCallbackMap; +std::map> g_publishCallbackMap; +std::map> g_authCallbackMap; +std::map> g_bindCallbackMap; +std::map> 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 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() >= 256) { + return ERR_INVALID_PARAMS; + } + return ERR_OK; +} + +inline 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; +} +} // 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 initCallback = std::make_shared(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 autoLock(g_initCallbackMapMutex); + g_initCallbackMap[bundleName_] = initCallback; + } + + std::lock_guard 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 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(malloc(sizeof(FfiDeviceBasicInfo) * result.size())); + if (deviceInfoList.head == nullptr) { + LOGE("Malloc failed"); + return DM_ERR_FAILED; + } + deviceInfoList.size = result.size(); + for (int64_t 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 discoveryCallback = nullptr; + { + std::lock_guard autoLock(g_discoveryCallbackMapMutex); + auto iter = g_DiscoveryCallbackMap.find(bundleName_); + if (iter == g_DiscoveryCallbackMap.end()) { + discoveryCallback = std::make_shared(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(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) +{ + LOGI("BindTarget in."); + if (DeviceManager::GetInstance().CheckNewAPIAccessPermission() != 0) { + return ERR_NO_PERMISSION; + } + int32_t ret = stringCheck(deviceId); + if (ret != 0) { + return ret; + } + LOGI("checkstring success."); + + callbackFinished = false; + if (isMetaType) { + std::shared_ptr bindTargetCallback = nullptr; + { + std::lock_guard autoLock(g_bindCallbackMapMutex); + auto iter = g_bindCallbackMap.find(bundleName_); + if (iter == g_bindCallbackMap.end()) { + bindTargetCallback = std::make_shared(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; + } + LOGI("register success."); + return WaitForCallbackCv(); + } + + std::shared_ptr bindDeviceCallback = nullptr; + { + std::lock_guard autoLock(g_authCallbackMapMutex); + auto iter = g_authCallbackMap.find(bundleName_); + if (iter == g_authCallbackMap.end()) { + bindDeviceCallback = std::make_shared(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; + } + LOGI("BindDevice return %{public}d", ret); + return WaitForCallbackCv(); +} + +int32_t DeviceManagerFfiImpl::WaitForCallbackCv() +{ + std::unique_lock autoLock(callbackFinishedMutex); + callbackFinishedCv.wait(autoLock, [this] { return this->callbackFinished; }); + LOGI("WaitForCallbackCv got notified, errCode is %{public}d", errCode_.load()); + return errCode_; +} + +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 autoLock(callbackLock); + if (deviceStateChangedCallback) { + auto ptr = static_cast(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 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 autoLock(callbackLock); + if (discoverSuccessCallback) { + auto ptr = static_cast(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 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 autoLock(g_authCallbackMapMutex); + g_authCallbackMap.erase(bundleName_); + callbackFinished = true; + callbackFinishedCv.notify_one(); +} + +void DeviceManagerFfiImpl::OnDmUiCall(const std::string ¶mJson) +{ + LOGI("OnCall for paramJson"); +} + +DeviceManagerFfiImpl *DeviceManagerFfiImpl::GetDeviceManagerFfi(std::string &bundleName) +{ + std::lock_guard 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 autoLock(g_deviceManagerMapMutex); + g_deviceManagerMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_initCallbackMapMutex); + g_initCallbackMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_deviceStatusCallbackMapMutex); + g_deviceStatusCallbackMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_discoveryCallbackMapMutex); + g_DiscoveryCallbackMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_publishCallbackMapMutex); + g_publishCallbackMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_authCallbackMapMutex); + g_authCallbackMap.erase(bundleName_); + } + { + std::lock_guard autoLock(g_bindCallbackMapMutex); + g_bindCallbackMap.erase(bundleName_); + } + return; +} + +int32_t DeviceManagerFfiImpl::BindTargetWarpper(const std::string &deviceId, + const std::string &bindParam, std::shared_ptr 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(); + } + if (IsString(bindParamObj, PARAM_KEY_BLE_MAC)) { + targetId.bleMac = bindParamObj[PARAM_KEY_BLE_MAC].get(); + } + if (IsString(bindParamObj, PARAM_KEY_WIFI_IP)) { + targetId.wifiIp = bindParamObj[PARAM_KEY_WIFI_IP].get(); + } + if (IsInt32(bindParamObj, PARAM_KEY_WIFI_PORT)) { + targetId.wifiPort = (uint16_t)(bindParamObj[PARAM_KEY_WIFI_PORT].get()); + } + + std::map bindParamMap; + InsertMapParames(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 autoLock(g_deviceStatusCallbackMapMutex); + if (g_deviceStatusCallbackMap.find(bundleName_) != g_deviceStatusCallbackMap.end()) { + LOGI("bundleName already register."); + return ERR_OK; + } + } + auto callback = std::make_shared(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 autoLock(g_deviceStatusCallbackMapMutex); + g_deviceStatusCallbackMap[bundleName_] = callback; + } + return ERR_OK; +} + +int32_t DeviceManagerFfiImpl::RegisterDiscoveryCallback() +{ + auto discoveryCallback = std::make_shared(bundleName_); + { + std::lock_guard autoLock(g_discoveryCallbackMapMutex); + g_DiscoveryCallbackMap[bundleName_] = discoveryCallback; + } + discoveryCallback->IncreaseRefCount(); + return ERR_OK; +} + +int32_t DeviceManagerFfiImpl::RegisterPublishCallback() +{ + auto publishCallback = std::make_shared(bundleName_); + { + std::lock_guard autoLock(g_publishCallbackMapMutex); + g_publishCallbackMap[bundleName_] = publishCallback; + } + publishCallback->IncreaseRefCount(); + return ERR_OK; +} + +int32_t DeviceManagerFfiImpl::RegisterReplyCallback() +{ + auto dmUiCallback = std::make_shared(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 autoLock(g_dmUiCallbackMapMutex); + g_dmUiCallbackMap[bundleName_] = dmUiCallback; + } + return ERR_OK; +} + +int32_t DeviceManagerFfiImpl::ReleaseDevStatusCallback() +{ + { + std::lock_guard 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 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 DiscoveryCallback = nullptr; + { + std::lock_guard 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 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 publishCallback = nullptr; + { + std::lock_guard 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 autoLock(g_publishCallbackMapMutex); + g_publishCallbackMap.erase(bundleName_); + } + return ERR_OK; +} + +int32_t DeviceManagerFfiImpl::ReleaseReplyCallback() +{ + { + std::lock_guard 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 autoLock(g_dmUiCallbackMapMutex); + g_dmUiCallbackMap.erase(bundleName_); + } + return ERR_OK; +} + + +void DeviceManagerFfiImpl::RegisterCallbackByType(const std::string &type, void *callback) +{ + std::lock_guard autoLock(callbackLock); + if (type == DM_FFI_EVENT_DEVICE_STATE_CHANGE) { + deviceStateChangedCallback = CJLambda::Create(reinterpret_cast(callback)); + } else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_SUCCESS) { + discoverSuccessCallback = CJLambda::Create(reinterpret_cast(callback)); + } else if (type == DM_FFI_EVENT_DEVICE_NAME_CHANGE) { + deviceNameChangedCallback = CJLambda::Create(reinterpret_cast(callback)); + } else if (type == DM_FFI_EVENT_DEVICE_DISCOVER_FAIL) { + deviceDiscoverFailedCallback = CJLambda::Create(reinterpret_cast(callback)); + } else { + LOGE("RegisterCallbackByType call with wrong type."); + } +} + +void DeviceManagerFfiImpl::Off(const std::string &type) +{ + std::lock_guard 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 diff --git a/interfaces/cj/src/device_manager_utils.cpp b/interfaces/cj/src/device_manager_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf3a8f5badacd70ffa05c1ac14f838ef73571001 --- /dev/null +++ b/interfaces/cj/src/device_manager_utils.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2022-2023 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 "device_manager_impl.h" + +#include +#include +#include + +#include "dm_log.h" +#include "dm_constants.h" +#include "dm_anonymous.h" + +namespace OHOS::DistributedHardware { + +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 ¶mJson) +{ + 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 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) +{ + int64_t len = strlen(in); + char *result = static_cast(malloc(len + 1)); + if (result == nullptr) { + LOGE("Malloc failed."); + return nullptr; + } + std::char_traits::copy(result, in, len+1); + return result; +} + +void InsertMapParames(nlohmann::json &bindParamObj, std::map &bindParamMap) +{ + LOGI("Insert map parames start"); + if (IsInt32(bindParamObj, AUTH_TYPE)) { + int32_t authType = bindParamObj[AUTH_TYPE].get(); + bindParamMap.insert(std::pair(PARAM_KEY_AUTH_TYPE, std::to_string(authType))); + } + if (IsString(bindParamObj, APP_OPERATION)) { + std::string appOperation = bindParamObj[APP_OPERATION].get(); + bindParamMap.insert(std::pair(PARAM_KEY_APP_OPER, appOperation)); + } + if (IsString(bindParamObj, CUSTOM_DESCRIPTION)) { + std::string appDescription = bindParamObj[CUSTOM_DESCRIPTION].get(); + bindParamMap.insert(std::pair(PARAM_KEY_APP_DESC, appDescription)); + } + if (IsString(bindParamObj, PARAM_KEY_TARGET_PKG_NAME)) { + std::string targetPkgName = bindParamObj[PARAM_KEY_TARGET_PKG_NAME].get(); + bindParamMap.insert(std::pair(PARAM_KEY_TARGET_PKG_NAME, targetPkgName)); + } + if (IsString(bindParamObj, PARAM_KEY_META_TYPE)) { + std::string metaType = bindParamObj[PARAM_KEY_META_TYPE].get(); + bindParamMap.insert(std::pair(PARAM_KEY_META_TYPE, metaType)); + } + if (IsString(bindParamObj, PARAM_KEY_PIN_CODE)) { + std::string pinCode = bindParamObj[PARAM_KEY_PIN_CODE].get(); + bindParamMap.insert(std::pair(PARAM_KEY_PIN_CODE, pinCode)); + } + if (IsString(bindParamObj, PARAM_KEY_AUTH_TOKEN)) { + std::string authToken = bindParamObj[PARAM_KEY_AUTH_TOKEN].get(); + bindParamMap.insert(std::pair(PARAM_KEY_AUTH_TOKEN, authToken)); + } + if (IsInt32(bindParamObj, BIND_LEVEL)) { + int32_t bindLevel = bindParamObj[BIND_LEVEL].get(); + bindParamMap.insert(std::pair(BIND_LEVEL, std::to_string(bindLevel))); + } +} +} // OHOS::DistributedHardware diff --git a/interfaces/kits/js4.0/src/native_devicemanager_js.cpp b/interfaces/kits/js4.0/src/native_devicemanager_js.cpp index 88e602eb947f32da7ec4f3b223e23f8d8510e0bc..4dad2e2aa4bbc69f2da17f62749c424166daa6a5 100644 --- a/interfaces/kits/js4.0/src/native_devicemanager_js.cpp +++ b/interfaces/kits/js4.0/src/native_devicemanager_js.cpp @@ -1567,6 +1567,10 @@ void DeviceManagerNapi::BindDevOrTarget(DeviceManagerNapi *deviceManagerWrapper, std::string bindParam; bool isMetaType = false; JsToBindParam(env, object, bindParam, authAsyncCallbackInfo_.authType, isMetaType); + LOGI("the bindParam is %{public}s", bindParam.c_str()); + LOGI("the isMetaType is %{public}d", isMetaType); + LOGI("the deviceId is %{public}s", deviceId.c_str()); + LOGI("the auth type is %{public}d", authAsyncCallbackInfo_.authType); if (isMetaType) { std::shared_ptr bindTargetCallback = nullptr;