From 97b100ec12d6e288e7a35db1ea1d2e78e6b0e11a Mon Sep 17 00:00:00 2001 From: zhuzhihui7 Date: Mon, 20 Jan 2025 11:26:47 +0800 Subject: [PATCH] Commit distributed camra connected to all connect. Signed-off-by: zhuzhihui7 --- .../constants/distributed_camera_errno.h | 4 + services/cameraservice/sinkservice/BUILD.gn | 1 + .../dcamera_sink_controller.cpp | 7 +- services/cameraservice/sourceservice/BUILD.gn | 1 + .../dcamera_source_dev.cpp | 37 ++ services/channel/BUILD.gn | 10 +- .../include/allconnect/dcamera_block_obj.h | 64 ++++ .../dcamera_collaboration_manager_capi.h | 91 +++++ .../distributed_camera_allconnect_manager.h | 85 +++++ .../channel/include/dcamera_softbus_adapter.h | 1 + .../distributed_camera_allconnect_manager.cpp | 354 ++++++++++++++++++ .../channel/src/dcamera_softbus_adapter.cpp | 88 +++++ .../test/unittest/common/channel/BUILD.gn | 2 + .../channel/dcamera_softbus_adapter_test.cpp | 15 + 14 files changed, 753 insertions(+), 7 deletions(-) create mode 100644 services/channel/include/allconnect/dcamera_block_obj.h create mode 100644 services/channel/include/allconnect/dcamera_collaboration_manager_capi.h create mode 100644 services/channel/include/allconnect/distributed_camera_allconnect_manager.h create mode 100644 services/channel/src/allconnect/distributed_camera_allconnect_manager.cpp diff --git a/common/include/constants/distributed_camera_errno.h b/common/include/constants/distributed_camera_errno.h index 1e2929ee..ba8c436f 100644 --- a/common/include/constants/distributed_camera_errno.h +++ b/common/include/constants/distributed_camera_errno.h @@ -35,6 +35,10 @@ namespace DistributedHardware { DCAMERA_UNREGIST_HAL_FAILED = -13, DCAMERA_ALLOC_ERROR = -14, DCAMERA_DEVICE_BUSY = -15, + DCAMERA_ERR_APPLY_RESULT = -16, + DCAMERA_ERR_DLOPEN = -17, + DCAMERA_ERR_PUBLISH_STATE = -18, + DCAMERA_ERR_ALLCONNECT = -19, }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sinkservice/BUILD.gn b/services/cameraservice/sinkservice/BUILD.gn index 19425d54..80bb9c4a 100644 --- a/services/cameraservice/sinkservice/BUILD.gn +++ b/services/cameraservice/sinkservice/BUILD.gn @@ -47,6 +47,7 @@ ohos_shared_library("distributed_camera_sink") { "${services_path}/cameraservice/cameraoperator/client/include/listener", "${services_path}/cameraservice/cameraoperator/handler/include", "${services_path}/channel/include", + "${services_path}/channel/include/allconnect", "${services_path}/data_process/include/eventbus", "${services_path}/data_process/include/interfaces", "${services_path}/data_process/include/pipeline", diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp index 327de1cd..9e2d39b2 100644 --- a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp @@ -553,9 +553,14 @@ void DCameraSinkController::OnSessionState(int32_t state, std::string networkId) case DCAMERA_CHANNEL_STATE_CONNECTED: HandleConnected(networkId); break; - case DCAMERA_CHANNEL_STATE_DISCONNECTED: + case DCAMERA_CHANNEL_STATE_DISCONNECTED: { + std::shared_ptr events = std::make_shared(); + events->eventType_ = DCAMERA_SINK_STOP; + events->eventResult_ = DCAMERA_EVENT_SINK_STOP; + DCameraNotify(events); HandleDisconnected(); break; + } default: DHLOGE("unknown session state"); break; diff --git a/services/cameraservice/sourceservice/BUILD.gn b/services/cameraservice/sourceservice/BUILD.gn index 95ca3e29..4b6bc930 100644 --- a/services/cameraservice/sourceservice/BUILD.gn +++ b/services/cameraservice/sourceservice/BUILD.gn @@ -47,6 +47,7 @@ ohos_shared_library("distributed_camera_source") { "${innerkits_path}/native_cpp/camera_source/include/callback", "${services_path}/cameraservice/base/include", "${services_path}/channel/include", + "${services_path}/channel/include/allconnect", "${services_path}/cameraservice/cameraoperator/handler/include", "${services_path}/data_process/include/eventbus", "${services_path}/data_process/include/interfaces", diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp index aafcbb92..1b01666f 100644 --- a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp @@ -28,6 +28,7 @@ #include "dcamera_source_controller.h" #include "dcamera_source_input.h" #include "dcamera_utils_tools.h" +#include "distributed_camera_allconnect_manager.h" namespace OHOS { namespace DistributedHardware { @@ -470,6 +471,29 @@ int32_t DCameraSourceDev::OpenCamera() return ret; } + ret = DCameraAllConnectManager::GetInstance().InitDCameraAllConnectManager(); + if (ret == DCAMERA_OK) { + auto resourceReq = DCameraAllConnectManager::GetInstance().BuildResourceRequest(); + ret = DCameraAllConnectManager::GetInstance().ApplyAdvancedResource(devId_, resourceReq.get()); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect apply advanced resource failed, ret: %{public}d, devId: %{public}s", + ret, GetAnonyString(devId_).c_str()); + return ret; + } + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(devId_, SCM_PREPARE); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect publish scm prepare failed, ret: %{public}d, devId: %{public}s", + ret, GetAnonyString(devId_).c_str()); + return ret; + } + } else { + // If we exit on the half way, whether we should do something to clean the former process? + DHLOGE("DCamera allconnect init and register lifecycle callback failed, ret: %{public}d, devId: %{public}s", + ret, GetAnonyString(devId_).c_str()); + return ret; + } + DHLOGI("DCamera allconnect register lifecyle and apply advanced resource scm prepare success"); + DcameraStartAsyncTrace(DCAMERA_OPEN_CHANNEL_CONTROL, DCAMERA_OPEN_CHANNEL_TASKID); ret = controller_->OpenChannel(openInfo); if (ret != DCAMERA_OK) { @@ -478,6 +502,7 @@ int32_t DCameraSourceDev::OpenCamera() DcameraFinishAsyncTrace(DCAMERA_OPEN_CHANNEL_CONTROL, DCAMERA_OPEN_CHANNEL_TASKID); return DCAMERA_OPEN_CONFLICT; } + CHECK_AND_RETURN_RET_LOG(stateListener_ == nullptr, DCAMERA_BAD_VALUE, "stateListener_ is nullptr."); stateListener_->OnHardwareStateChanged(devId_, dhId_, DcameraBusinessState::RUNNING); return DCAMERA_OK; @@ -498,6 +523,18 @@ int32_t DCameraSourceDev::CloseCamera() DHLOGE("DCameraSourceDev Execute CloseCamera controller CloseChannel failed, ret: %{public}d, devId: " "%{public}s dhId: %{public}s", ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); } + + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(devId_, SCM_IDLE); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect source CloseCamera PublishServiceState failed, ret: %{public}d, devId: %{public}s ", + ret, GetAnonyString(devId_).c_str()); + } + + ret = DCameraAllConnectManager::GetInstance().UnInitDCameraAllConnectManager(); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect source CloseCamera UnInitDCameraAll failed, ret: %{public}d, devId: %{public}s", + ret, GetAnonyString(devId_).c_str()); + } CHECK_AND_RETURN_RET_LOG(stateListener_ == nullptr, DCAMERA_BAD_VALUE, "stateListener_ is nullptr."); stateListener_->OnHardwareStateChanged(devId_, dhId_, DcameraBusinessState::IDLE); return DCAMERA_OK; diff --git a/services/channel/BUILD.gn b/services/channel/BUILD.gn index 61f2de56..f39c1956 100644 --- a/services/channel/BUILD.gn +++ b/services/channel/BUILD.gn @@ -30,16 +30,20 @@ ohos_shared_library("distributed_camera_channel") { include_dirs = [ "include", + "include/allconnect", "${common_path}/include/constants", "${common_path}/include/utils", "${feeding_smoother_path}/base", "${feeding_smoother_path}/derived", "${feeding_smoother_path}/utils", "${services_path}/cameraservice/base/include", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr", ] sources = [ + "${services_path}/cameraservice/base/src/dcamera_info_cmd.cpp", "${services_path}/cameraservice/base/src/dcamera_sink_frame_info.cpp", + "src/allconnect/distributed_camera_allconnect_manager.cpp", "src/dcamera_channel_sink_impl.cpp", "src/dcamera_channel_source_impl.cpp", "src/dcamera_low_latency.cpp", @@ -48,12 +52,6 @@ ohos_shared_library("distributed_camera_channel") { "src/dcamera_softbus_session.cpp", ] - ldflags = [ - "-fpie", - "-Wl,-z,relro", - "-Wl,-z,now", - ] - deps = [ "${common_path}:distributed_camera_utils" ] defines = [ diff --git a/services/channel/include/allconnect/dcamera_block_obj.h b/services/channel/include/allconnect/dcamera_block_obj.h new file mode 100644 index 00000000..b892985a --- /dev/null +++ b/services/channel/include/allconnect/dcamera_block_obj.h @@ -0,0 +1,64 @@ +/* +* 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 DCAMERA_BLOCK_OBJECT_H +#define DCAMERA_BLOCK_OBJECT_H + +#include +#include + +namespace OHOS { +namespace DistributedHardware { +template +class DCameraBlockObject { +public: + explicit DCameraBlockObject(uint32_t interval, const T &invalid = T()) : interval_(interval), data_(invalid) + { + } + ~DCameraBlockObject() = default; + + void SetValue(T data) + { + std::lock_guard lock(mutex_); + data_ = std::move(data); + isSet_ = true; + cv_.notify_one(); + } + + T GetValue() + { + std::unique_lock lock(mutex_); + cv_.wait_for(lock, std::chrono::milliseconds(interval_), [this]() { return isSet_; }); + isSet_ = false; + T data = std::move(data_); + cv_.notify_one(); + return data; + } + + void SetInterval(uint32_t interval) + { + interval_ = interval; + } + +private: + uint32_t interval_; + bool isSet_ = false; + std::mutex mutex_; + std::condition_variable cv_; + T data_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DCAMERA_BLOCK_OBJECT_H \ No newline at end of file diff --git a/services/channel/include/allconnect/dcamera_collaboration_manager_capi.h b/services/channel/include/allconnect/dcamera_collaboration_manager_capi.h new file mode 100644 index 00000000..ede26db3 --- /dev/null +++ b/services/channel/include/allconnect/dcamera_collaboration_manager_capi.h @@ -0,0 +1,91 @@ +/* +* 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 DCAMERA_COLLABORATION_MANAGER_CAPI_H +#define DCAMERA_COLLABORATION_MANAGER_CAPI_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum DCameraCollaborationHardwareType { + SCM_UNKNOWN_TYPE = 0, + SCM_DISPLAY = 1, + SCM_MIC = 2, + SCM_SPEAKER = 3, + SCM_CAMERA = 4, +} DCameraCollaborationHardwareType; + +typedef enum DCameraCollaborationBussinessStatus { + SCM_IDLE = 1, + SCM_PREPARE = 2, + SCM_CONNECTING = 3, + SCM_CONNECTED = 4 +} DCameraCollaborationBussinessStatus; + +typedef enum DCameraCollaborationResultCode { + PASS = 1004720001, + REJECT = 1004720002 +} DCameraCollaborationResultCode; + +typedef struct DCameraCollaboration_HardwareRequestInfo { + DCameraCollaborationHardwareType hardWareType; + bool canShare; +} DCameraCollaborationHardwareRequestInfo; + +typedef struct DCameraCollaborationCommunicationRequestInfo { + int32_t minBandwidth; + int32_t maxLatency; + int32_t minLatency; + int32_t maxWaitTime; + const char *dataType; +} DCameraCollaborationCommunicationRequestInfo; + +typedef struct DCameraCollaborationResourceRequestInfoSets { + uint32_t remoteHardwareListSize; + DCameraCollaboration_HardwareRequestInfo *remoteHardwareList; + uint32_t localHardwareListSize; + DCameraCollaboration_HardwareRequestInfo *localHardwareList; + DCameraCollaborationCommunicationRequestInfo *communicationRequest; +} DCameraCollaborationResourceRequestInfoSets; + +typedef struct DCameraCollaborationCallback { + int32_t (*onStop)(const char *peerNetworkId); + int32_t (*applyResult)(int32_t errorcode, int32_t result, const char *reason); +} DCameraCollaborationCallback; + +typedef struct DCameraCollaborationApi { + int32_t (*dCameraCollaborationPublishServiceState)(const char *peerNetworkId, const char *serviceName, + const char *extraInfo, DCameraCollaborationBussinessStatus state); + int32_t (*dCameraCollaborationApplyAdvancedResource)(const char *peerNetworkId, const char *serviceName, + DCameraCollaborationResourceRequestInfoSets *resourceRequest, + DCameraCollaborationCallback *callback); + int32_t (*dCameraCollaborationRegisterLifecycleCallback)(const char *serviceName, + DCameraCollaborationCallback *callback); + int32_t (*dCameraCollaborationUnRegisterLifecycleCallback)(const char *serviceName); +} DCameraCollaborationApi; + +int32_t DCameraCollaborationExport(DCameraCollaborationApi *exportapi); + +#ifdef __cplusplus +} +#endif + +#endif // DCAMERA_COLLABORATION_MANAGER_CAPI_H \ No newline at end of file diff --git a/services/channel/include/allconnect/distributed_camera_allconnect_manager.h b/services/channel/include/allconnect/distributed_camera_allconnect_manager.h new file mode 100644 index 00000000..3de5b072 --- /dev/null +++ b/services/channel/include/allconnect/distributed_camera_allconnect_manager.h @@ -0,0 +1,85 @@ +/* +* 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 DISTRIBUTEDCAMERA_ALL_CONNECT_MANAGER_H +#define DISTRIBUTEDCAMERA_ALL_CONNECT_MANAGER_H + +#include +#include +#include +#include + +#include "dcamera_block_obj.h" +#include "dcamera_collaboration_manager_capi.h" +#include "distributed_camera_errno.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraAllConnectManager { +public: + static DCameraAllConnectManager &GetInstance(); + int32_t InitDCameraAllConnectManager(); + int32_t UnInitDCameraAllConnectManager(); + int32_t PublishServiceState(const std::string &peerNetworkId, + DCameraCollaborationBussinessStatus state); + int32_t ApplyAdvancedResource(const std::string &peerNetworkId, + DCameraCollaborationResourceRequestInfoSets *resourceRequest); + std::shared_ptr BuildResourceRequest(); + + static void SetSourceNetworkId(const std::string &networkId, int32_t socket); + static void SetSinkNetWorkId(const std::string &networkId, int32_t socket); + static void RemoveSinkNetworkId(int32_t sessionId); + static void RemoveSourceNetworkId(int32_t sessionId); + static std::string GetSinkDevIdBySocket(int32_t socket); + static int32_t GetSinkSocketByNetWorkId(const std::string &networkId); + static int32_t GetSourceSocketByNetworkId(const std::string &networkId); +private: + DCameraAllConnectManager(); + ~DCameraAllConnectManager() = default; + int32_t GetAllConnectSoLoad(); + int32_t RegisterLifecycleCallback(); + int32_t UnRegisterLifecycleCallback(); + + static int32_t OnStop(const char *peerNetworkId); + static int32_t ApplyResult(int32_t errorcode, int32_t result, const char *reason); + + std::mutex allConnectLock_; + void *dllHandle_ = nullptr; + + DCameraCollaborationApi allConnect_ = { + .dCameraCollaborationPublishServiceState = nullptr, + .dCameraCollaborationApplyAdvancedResource = nullptr, + .dCameraCollaborationRegisterLifecycleCallback = nullptr, + .dCameraCollaborationUnRegisterLifecycleCallback = nullptr, + }; + DCameraCollaborationCallback allConnectCallback_; + std::shared_ptr remoteHardwareList_; + std::shared_ptr localHardwareList_; + std::shared_ptr communicationRequest_; + + static std::shared_ptr> applyResultBlock_; + static constexpr uint32_t BLOCK_INTERVAL_ALLCONNECT = 60 * 1000; + static inline const std::string SERVICE_NAME {"DistributedCamera"}; // to be discussed + + static std::map netwkIdSourceSessionIdMap_; + static std::mutex netwkIdSourceSessionIdMapLock_; + + static std::map netwkIdSinkSessionIdMap_; + static std::mutex netwkIdSinkSessionIdMapLock_; +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTEDCAMERA_ALL_CONNECT_MANAGER_H \ No newline at end of file diff --git a/services/channel/include/dcamera_softbus_adapter.h b/services/channel/include/dcamera_softbus_adapter.h index beeaeb88..f5d4db30 100644 --- a/services/channel/include/dcamera_softbus_adapter.h +++ b/services/channel/include/dcamera_softbus_adapter.h @@ -66,6 +66,7 @@ public: int32_t HandleSourceStreamExt(std::shared_ptr& buffer, const StreamData *ext); void RecordSourceSocketSession(int32_t socket, std::shared_ptr session); + void CloseSessionWithNetWorkId(const std::string &networkId); public: std::map> sinkSessions_; diff --git a/services/channel/src/allconnect/distributed_camera_allconnect_manager.cpp b/services/channel/src/allconnect/distributed_camera_allconnect_manager.cpp new file mode 100644 index 00000000..10212545 --- /dev/null +++ b/services/channel/src/allconnect/distributed_camera_allconnect_manager.cpp @@ -0,0 +1,354 @@ +/* +* 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 "distributed_camera_allconnect_manager.h" + +#include +#include +#include +#include + +#include "dcamera_protocol.h" +#include "dcamera_softbus_adapter.h" +#include "distributed_hardware_log.h" +#include "distributed_camera_errno.h" + +namespace OHOS { +namespace DistributedHardware { +#ifdef __LP64__ +constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib64/"; +#else +constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib/"; +#endif +constexpr const char *ALL_CONNECT_SO_NAME = "libcfwk_allconnect_client.z.so"; +std::shared_ptr> DCameraAllConnectManager::applyResultBlock_; +constexpr int32_t DFS_QOS_TYPE_MIN_BW = 90 * 1024 * 1024; +constexpr int32_t DFS_QOS_TYPE_MAX_LATENCY = 10000; +constexpr int32_t DFS_QOS_TYPE_MIN_LATENCY = 2000; +DCameraAllConnectManager::DCameraAllConnectManager() +{ + allConnectCallback_.onStop = &DCameraAllConnectManager::OnStop; + allConnectCallback_.applyResult = &DCameraAllConnectManager::ApplyResult; +} + +DCameraAllConnectManager &DCameraAllConnectManager::GetInstance() +{ + static DCameraAllConnectManager instance; + return instance; +} + +std::mutex DCameraAllConnectManager::netwkIdSourceSessionIdMapLock_; +std::map DCameraAllConnectManager::netwkIdSourceSessionIdMap_; +std::mutex DCameraAllConnectManager::netwkIdSinkSessionIdMapLock_; +std::map DCameraAllConnectManager::netwkIdSinkSessionIdMap_; + +int32_t DCameraAllConnectManager::InitDCameraAllConnectManager() +{ + DHLOGI("DCamera allconnect InitDCameraAllConnectManager begin"); + int32_t ret = GetAllConnectSoLoad(); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect InitDCameraAllConnectManager failed, so not exist or load so error, ret %{public}d", + ret); + return ret; + } + + ret = RegisterLifecycleCallback(); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect InitDCameraAllConnectManager failed, register lifecycle error,ret %{public}d", + ret); + return ret; + } + DHLOGI("DCamera allconnect InitDCameraAllConnectManager success"); + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::UnInitDCameraAllConnectManager() +{ + DHLOGI("DCamera allconnect UnInitDCameraAllConnectManager begin"); + int32_t ret = UnRegisterLifecycleCallback(); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect UnInitDCameraAllConnectManager failed, unregister error,ret %{public}d", ret); + } + dlclose(dllHandle_); + dllHandle_ = nullptr; + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::PublishServiceState(const std::string &peerNetworkId, + DCameraCollaborationBussinessStatus state) +{ + DHLOGI("DCamera allconnect PublishServiceState begin"); + std::lock_guard lock(allConnectLock_); + if (dllHandle_ == nullptr) { + DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support."); + return DistributedCameraErrno::DCAMERA_OK; + } + if (allConnect_.dCameraCollaborationPublishServiceState == nullptr) { + DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + int32_t ret = allConnect_.dCameraCollaborationPublishServiceState(peerNetworkId.c_str(), + SERVICE_NAME.c_str(), + "", state); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect PublishServiceState %{public}d fail, ret %{public}d", state, ret); + return DistributedCameraErrno::DCAMERA_ERR_PUBLISH_STATE; + } + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::ApplyAdvancedResource(const std::string &peerNetworkId, + DCameraCollaborationResourceRequestInfoSets *resourceRequest) +{ + DHLOGI("DCamera allconnect ApplyAdvancedResource begin"); + std::lock_guard lock(allConnectLock_); + if (dllHandle_ == nullptr) { + DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support."); + return DistributedCameraErrno::DCAMERA_OK; + } + if (allConnect_.dCameraCollaborationApplyAdvancedResource == nullptr) { + DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + if (applyResultBlock_ == nullptr) { + applyResultBlock_ = std::make_shared>(BLOCK_INTERVAL_ALLCONNECT, false); + } + + int32_t ret = allConnect_.dCameraCollaborationApplyAdvancedResource(peerNetworkId.c_str(), + SERVICE_NAME.c_str(), + resourceRequest, + &allConnectCallback_); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect ApplyAdvancedResource fail, ret %{public}d", ret); + return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT; + } + auto success = applyResultBlock_->GetValue(); + if (!success) { + DHLOGE("DCamera allconnect applyResult is reject"); + return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT; + } + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::GetAllConnectSoLoad() +{ + DHLOGI("DCamera allconnect GetAllConnectSoLoad begin"); + std::lock_guard lock(allConnectLock_); + char path[PATH_MAX + 1] = {0x00}; + std::string soPathName = std::string(ALL_CONNECT_SO_PATH) + std::string(ALL_CONNECT_SO_NAME); + if (soPathName.empty() || (soPathName.length() > PATH_MAX) || (realpath(soPathName.c_str(), path) == nullptr)) { + DHLOGE("DCamera allconnect all connect so load failed, soPath=%{public}s not exist.", soPathName.c_str()); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + int32_t (*allConnectProxy)(DCameraCollaborationApi *exportapi) = nullptr; + + dllHandle_ = dlopen(path, RTLD_LAZY); + if (dllHandle_ == nullptr) { + DHLOGE("DCamera allconnect dlopen fail"); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + allConnectProxy = reinterpret_cast( + dlsym(dllHandle_, "ServiceCollaborationManager_Export")); + if (allConnectProxy == nullptr) { + dlclose(dllHandle_); + dllHandle_ = nullptr; + DHLOGE("DCamera allconnect dlsym allConnectProxy fail"); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + int32_t ret = allConnectProxy(&allConnect_); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + dlclose(dllHandle_); + dllHandle_ = nullptr; + DHLOGE("DCamera allconnect get function struct fail, ret %{public}d", ret); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + DHLOGI("DCamera allconnect so load success"); + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::RegisterLifecycleCallback() +{ + DHLOGI("DCamera allconnect RegisterLifecycleCallback begin"); + std::lock_guard lock(allConnectLock_); + if (dllHandle_ == nullptr) { + DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + if (allConnect_.dCameraCollaborationRegisterLifecycleCallback == nullptr) { + DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + int32_t ret = allConnect_.dCameraCollaborationRegisterLifecycleCallback(SERVICE_NAME.c_str(), + &allConnectCallback_); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect RegisterLifecycleCallback fail, ret %{public}d", ret); + return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT; + } + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::UnRegisterLifecycleCallback() +{ + DHLOGI("DCamera allconnect UnRegisterLifecycleCallback begin"); + std::lock_guard lock(allConnectLock_); + if (dllHandle_ == nullptr) { + DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + if (allConnect_.dCameraCollaborationUnRegisterLifecycleCallback == nullptr) { + DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load."); + return DistributedCameraErrno::DCAMERA_ERR_DLOPEN; + } + + int32_t ret = allConnect_.dCameraCollaborationUnRegisterLifecycleCallback(SERVICE_NAME.c_str()); + if (ret != DistributedCameraErrno::DCAMERA_OK) { + DHLOGE("DCamera allconnect UnRegisterLifecycleCallback fail, ret %{public}d", ret); + return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT; + } + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::ApplyResult(int32_t errorcode, int32_t result, const char *reason) +{ + DHLOGI("DCamera allconnect ApplyResult begin"); + if (result != PASS) { + DHLOGE("DCamera allconnect Apply Result is Reject, errorcode is %{}d, reason is %{public}s", errorcode, reason); + applyResultBlock_->SetValue(false); + return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT; + } + applyResultBlock_->SetValue(true); + return DistributedCameraErrno::DCAMERA_OK; +} + +int32_t DCameraAllConnectManager::OnStop(const char *peerNetworkId) +{ + DHLOGI("DCamera allconnect OnStop begin peerNetworkId:%{public}s", peerNetworkId); + DCameraSoftbusAdapter::GetInstance().CloseSessionWithNetWorkId(peerNetworkId); + + return DistributedCameraErrno::DCAMERA_OK; +} + +std::shared_ptr DCameraAllConnectManager::BuildResourceRequest() +{ + auto resourceRequest = std::make_shared(); + + if (remoteHardwareList_ == nullptr) { + remoteHardwareList_ = std::make_shared(); + remoteHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA; + remoteHardwareList_->canShare = true; + } + resourceRequest->remoteHardwareListSize = 1; + resourceRequest->remoteHardwareList = remoteHardwareList_.get(); + + if (localHardwareList_ == nullptr) { + localHardwareList_ = std::make_shared(); + localHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA; + localHardwareList_->canShare = true; + } + resourceRequest->localHardwareListSize = 1; + resourceRequest->localHardwareList = localHardwareList_.get(); + + if (communicationRequest_ == nullptr) { + communicationRequest_ = std::make_shared(); + communicationRequest_->minBandwidth = DFS_QOS_TYPE_MIN_BW; + communicationRequest_->maxLatency = DFS_QOS_TYPE_MAX_LATENCY; + communicationRequest_->minLatency = DFS_QOS_TYPE_MIN_LATENCY; + communicationRequest_->maxWaitTime = 0; + communicationRequest_->dataType = "DATA_TYPE_VIDEO_STREAM"; + } + resourceRequest->communicationRequest = communicationRequest_.get(); + + return resourceRequest; +} +void DCameraAllConnectManager::RemoveSinkNetworkId(int32_t sessionId) +{ + std::lock_guard lock(netwkIdSinkSessionIdMapLock_); + for (auto it: netwkIdSinkSessionIdMap_) { + if (it.second == sessionId) { + netwkIdSinkSessionIdMap_.erase(it.first); + break; + } + } +} +void DCameraAllConnectManager::RemoveSourceNetworkId(int32_t sessionId) +{ + std::lock_guard lock(netwkIdSourceSessionIdMapLock_); + for (auto it: netwkIdSourceSessionIdMap_) { + if (it.second == sessionId) { + netwkIdSourceSessionIdMap_.erase(it.first); + break; + } + } +} +void DCameraAllConnectManager::SetSourceNetworkId(const std::string &networkId, int32_t socket) +{ + if (networkId.empty()) { + return ; + } + if (socket < 0) { + return ; + } + std::lock_guard lock(netwkIdSourceSessionIdMapLock_); + netwkIdSourceSessionIdMap_[networkId] = socket; +} +void DCameraAllConnectManager::SetSinkNetWorkId(const std::string &networkId, int32_t socket) +{ + if (networkId.empty()) { + return ; + } + if (socket < 0) { + return ; + } + std::lock_guard lock(netwkIdSinkSessionIdMapLock_); + netwkIdSinkSessionIdMap_[networkId] = socket; +} +std::string DCameraAllConnectManager::GetSinkDevIdBySocket(int32_t socket) +{ + std::lock_guard lock(netwkIdSinkSessionIdMapLock_); + for (auto it: netwkIdSinkSessionIdMap_) { + if (it.second == socket) { + return it.first; + } + } + return ""; +} +int32_t DCameraAllConnectManager::GetSinkSocketByNetWorkId(const std::string &networkId) +{ + int32_t sessionId = -1; + std::lock_guard lock(netwkIdSinkSessionIdMapLock_); + auto it = netwkIdSinkSessionIdMap_.find(networkId); + if (it != netwkIdSinkSessionIdMap_.end()) { + sessionId = it->second; + } + return sessionId; +} +int32_t DCameraAllConnectManager::GetSourceSocketByNetworkId(const std::string &networkId) +{ + int32_t sessionId = -1; + std::lock_guard lock(netwkIdSourceSessionIdMapLock_); + auto it = netwkIdSourceSessionIdMap_.find(networkId); + if (it != netwkIdSourceSessionIdMap_.end()) { + sessionId = it->second; + } + return sessionId; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/channel/src/dcamera_softbus_adapter.cpp b/services/channel/src/dcamera_softbus_adapter.cpp index d268ef15..ff993cea 100644 --- a/services/channel/src/dcamera_softbus_adapter.cpp +++ b/services/channel/src/dcamera_softbus_adapter.cpp @@ -26,6 +26,9 @@ #include "softbus_error_code.h" #include "dcamera_utils_tools.h" #include "dcamera_frame_info.h" +#include "distributed_camera_allconnect_manager.h" +#include "dcamera_event_cmd.h" +#include "dcamera_protocol.h" namespace OHOS { namespace DistributedHardware { @@ -236,6 +239,10 @@ int32_t DCameraSoftbusAdapter::CreateSoftBusSourceSocketClient(std::string myDev return DCAMERA_BAD_VALUE; } sourceSocketId_ = socketId; + if (peerSessionName.find("_control") != std::string::npos) { + DCameraAllConnectManager::GetInstance().PublishServiceState(peerDevId, SCM_CONNECTED); + DCameraAllConnectManager::SetSourceNetworkId(peerDevId, sourceSocketId_); + } DHLOGI("create socket client end, myDevId: %{public}s, peerSessionName: %{public}s", GetAnonyString(myDevId).c_str(), GetAnonyString(peerSessionName).c_str()); return socketId; @@ -351,6 +358,13 @@ int32_t DCameraSoftbusAdapter::SourceOnBind(int32_t socket, PeerSocketInfo info) if (ret != DCAMERA_OK) { DHLOGE("source bind socket failed, ret: %{public}d socket: %{public}d", ret, socket); } + if (session->GetPeerSessionName().find("_control") != std::string::npos) { + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(info.networkId, SCM_CONNECTED); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect sourceonBind publish scm connected failed, ret: %{public}d", ret); + } + DCameraAllConnectManager::SetSourceNetworkId(info.networkId, socket); + } DHLOGI("source bind socket end, socket: %{public}d end", socket); return ret; } @@ -365,6 +379,9 @@ void DCameraSoftbusAdapter::SourceOnShutDown(int32_t socket, ShutdownReason reas return; } session->OnSessionClose(socket); + if (session->GetPeerSessionName().find("_control") != std::string::npos) { + DCameraAllConnectManager::RemoveSourceNetworkId(socket); + } DHLOGI("source on shutdown socket end socket: %{public}d end", socket); return; } @@ -564,6 +581,19 @@ int32_t DCameraSoftbusAdapter::SinkOnBind(int32_t socket, PeerSocketInfo info) if (ret != DCAMERA_OK) { DHLOGE("sink bind socket error, not find socket %{public}d", socket); } + if (session->GetPeerSessionName().find("_control") != std::string::npos) { + ret = DCameraAllConnectManager::GetInstance().InitDCameraAllConnectManager(); + if (ret == DCAMERA_OK) { + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(info.networkId, SCM_CONNECTED); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect sink on bind, publish service state failed %{public}d", ret); + } + } else { + DHLOGE("DCamera allconnect sink on bind, InitDCameraAllConnectManager failed %{public}d", ret); + } + + DCameraAllConnectManager::SetSinkNetWorkId(info.networkId, socket); + } DHLOGI("sink bind socket end, socket: %{public}d", socket); return ret; } @@ -578,6 +608,23 @@ void DCameraSoftbusAdapter::SinkOnShutDown(int32_t socket, ShutdownReason reason return; } session->OnSessionClose(socket); + if (session->GetPeerSessionName().find("_control") != std::string::npos) { + std::string devId = DCameraAllConnectManager::GetSinkDevIdBySocket(socket); + if (!devId.empty()) { + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(devId, SCM_IDLE); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect sinkDown PublishServiceState failed, ret: %{public}d, devId: %{public}s ", + ret, GetAnonyString(devId).c_str()); + } + + ret = DCameraAllConnectManager::GetInstance().UnInitDCameraAllConnectManager(); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect sinkdown UnInitDCameraAllConn failed, ret: %{public}d, devId: %{public}s", + ret, GetAnonyString(devId).c_str()); + } + } + DCameraAllConnectManager::RemoveSinkNetworkId(socket); + } DHLOGI("sink on shutdown socket end, socket: %{public}d", socket); return; } @@ -652,5 +699,46 @@ int32_t DCameraSoftbusAdapter::GetLocalNetworkId(std::string& myDevId) myDevId = std::string(basicInfo.networkId); return DCAMERA_OK; } +void DCameraSoftbusAdapter::CloseSessionWithNetWorkId(const std::string &networkId) +{ + DHLOGI("DCamera allconnect CloseSessionWithNetworkId begin"); + if (networkId.empty()) { + DHLOGE("DCamera allconnect peerNetworkId is empty"); + return; + } + int32_t sessionId = DCameraAllConnectManager::GetSinkSocketByNetWorkId(networkId); + std::shared_ptr session = nullptr; + int32_t ret = DCAMERA_OK; + bool bSinkConflict = false; + if (sessionId != -1) { + ret = DCameraSoftbusSinkGetSession(sessionId, session); + bSinkConflict = true; + } else { + sessionId = DCameraAllConnectManager::GetSourceSocketByNetworkId(networkId); + if (sessionId != -1) { + ret = DCameraSoftbusSourceGetSession(sessionId, session); + } else { + DHLOGE("DCamera allconnect CloseSessionWithNetWorkId can not find socket"); + return; + } + } + if (ret != DCAMERA_OK || session == nullptr) { + DHLOGE("DCamera allconnect CloseSessionWithNetWorkId can not find session %{public}d", sessionId); + return; + } + session->OnSessionClose(sessionId); + Shutdown(sessionId); + if (bSinkConflict) { + ret = DCameraAllConnectManager::GetInstance().PublishServiceState(networkId, SCM_IDLE); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect CloseSessionWithNetworkId publish service state failed"); + } + ret = DCameraAllConnectManager::GetInstance().UnInitDCameraAllConnectManager(); + if (ret != DCAMERA_OK) { + DHLOGE("DCamera allconnect CloseSessionWithNetworkId UnInitDCameraAllConnectManager failed"); + } + } +} + } // namespace DistributedHardware } // namespace OHOS diff --git a/services/channel/test/unittest/common/channel/BUILD.gn b/services/channel/test/unittest/common/channel/BUILD.gn index e684ee6e..64a9eccf 100644 --- a/services/channel/test/unittest/common/channel/BUILD.gn +++ b/services/channel/test/unittest/common/channel/BUILD.gn @@ -25,6 +25,7 @@ config("module_private_config") { "${common_path}/include/utils", "${services_path}/cameraservice/base/include", "${services_path}/channel/include", + "${services_path}/channel/include/allconnect", "${services_path}/channel/test/unittest/common/channel", "${services_path}/cameraservice/cameraoperator/client/include", "${services_path}/cameraservice/cameraoperator/client/include/callback", @@ -53,6 +54,7 @@ ohos_unittest("DCameraChannelTest") { sources = [ "${services_path}/cameraservice/base/src/dcamera_sink_frame_info.cpp", + "${services_path}/channel/src/allconnect/distributed_camera_allconnect_manager.cpp", "${services_path}/channel/src/dcamera_channel_sink_impl.cpp", "${services_path}/channel/src/dcamera_channel_source_impl.cpp", "${services_path}/channel/src/dcamera_softbus_adapter.cpp", diff --git a/services/channel/test/unittest/common/channel/dcamera_softbus_adapter_test.cpp b/services/channel/test/unittest/common/channel/dcamera_softbus_adapter_test.cpp index d13b7b19..2e52fde2 100644 --- a/services/channel/test/unittest/common/channel/dcamera_softbus_adapter_test.cpp +++ b/services/channel/test/unittest/common/channel/dcamera_softbus_adapter_test.cpp @@ -899,5 +899,20 @@ HWTEST_F(DCameraSoftbusAdapterTest, dcamera_softbus_adapter_test_034, TestSize.L DCameraSoftbusAdapter::GetInstance().DestroySoftbusSessionServer(sessionName); EXPECT_EQ(DCAMERA_OK, ret); } + +HWTEST_F(DCameraSoftbusAdapterTest, DCameraSoftbusAdapterTest_035, TestSize.Level1) +{ + DCameraSoftbusAdapter::GetInstance().CloseSessionWithNetWorkId(""); + std::string sessionName = "sourcetest035"; + DCAMERA_CHANNEL_ROLE role = DCAMERA_CHANNLE_ROLE_SOURCE; + std::string mySessName = "sourcetest035"; + std::string peerSessName = "sinktest02"; + DCameraSessionMode sessionMode = DCameraSessionMode::DCAMERA_SESSION_MODE_VIDEO; + std::string peerDevId = TEST_DEVICE_ID; + std::string myDevId = "abcde"; + DCameraSoftbusAdapter::GetInstance().CreateSoftBusSourceSocketClient(myDevId, peerSessName, peerDevId, + sessionMode, role); + DCameraSoftbusAdapter::GetInstance().CloseSessionWithNetWorkId("testNetworkId"); +} } } \ No newline at end of file -- Gitee