1e0e9324cSopenharmony_ci/* 2e0e9324cSopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3e0e9324cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0e9324cSopenharmony_ci * you may not use this file except in compliance with the License. 5e0e9324cSopenharmony_ci * You may obtain a copy of the License at 6e0e9324cSopenharmony_ci * 7e0e9324cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0e9324cSopenharmony_ci * 9e0e9324cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0e9324cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0e9324cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0e9324cSopenharmony_ci * See the License for the specific language governing permissions and 13e0e9324cSopenharmony_ci * limitations under the License. 14e0e9324cSopenharmony_ci */ 15e0e9324cSopenharmony_ci 16e0e9324cSopenharmony_ci#include "context_manager.h" 17e0e9324cSopenharmony_ci#include "common/common_macro.h" 18e0e9324cSopenharmony_ci#include "common/const_def.h" 19e0e9324cSopenharmony_ci#include "common/event_comm.h" 20e0e9324cSopenharmony_ci#include "common/sharing_log.h" 21e0e9324cSopenharmony_ci#include "configuration/include/config.h" 22e0e9324cSopenharmony_ci#include "magic_enum.hpp" 23e0e9324cSopenharmony_ci#include "network/network_session_manager.h" 24e0e9324cSopenharmony_ci 25e0e9324cSopenharmony_cinamespace OHOS { 26e0e9324cSopenharmony_cinamespace Sharing { 27e0e9324cSopenharmony_ci 28e0e9324cSopenharmony_ciContextManager::~ContextManager() 29e0e9324cSopenharmony_ci{ 30e0e9324cSopenharmony_ci SHARING_LOGD("id: %{public}s.", std::string(magic_enum::enum_name(ModuleType::MODULE_CONTEXT)).c_str()); 31e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 32e0e9324cSopenharmony_ci contexts_.clear(); 33e0e9324cSopenharmony_ci} 34e0e9324cSopenharmony_ci 35e0e9324cSopenharmony_civoid ContextManager::Init() 36e0e9324cSopenharmony_ci{ 37e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 38e0e9324cSopenharmony_ci SharingValue::Ptr values = nullptr; 39e0e9324cSopenharmony_ci auto ret = Config::GetInstance().GetConfig("context", "agentLimit", "maxSinkAgent", values); 40e0e9324cSopenharmony_ci if (ret == CONFIGURE_ERROR_NONE) { 41e0e9324cSopenharmony_ci int32_t value; 42e0e9324cSopenharmony_ci values->GetValue<int32_t>(value); 43e0e9324cSopenharmony_ci maxSinkAgent_ = static_cast<uint32_t>(value); 44e0e9324cSopenharmony_ci } else { 45e0e9324cSopenharmony_ci maxSinkAgent_ = MAX_SINK_AGENT_NUM; 46e0e9324cSopenharmony_ci } 47e0e9324cSopenharmony_ci 48e0e9324cSopenharmony_ci ret = Config::GetInstance().GetConfig("context", "agentLimit", "maxSrcAgent", values); 49e0e9324cSopenharmony_ci if (ret == CONFIGURE_ERROR_NONE) { 50e0e9324cSopenharmony_ci int32_t value; 51e0e9324cSopenharmony_ci values->GetValue<int32_t>(value); 52e0e9324cSopenharmony_ci maxSrcAgent_ = static_cast<uint32_t>(value); 53e0e9324cSopenharmony_ci } else { 54e0e9324cSopenharmony_ci maxSrcAgent_ = MAX_SRC_AGENT_NUM; 55e0e9324cSopenharmony_ci } 56e0e9324cSopenharmony_ci 57e0e9324cSopenharmony_ci ret = Config::GetInstance().GetConfig("context", "agentLimit", "maxContext", values); 58e0e9324cSopenharmony_ci if (ret == CONFIGURE_ERROR_NONE) { 59e0e9324cSopenharmony_ci int32_t value; 60e0e9324cSopenharmony_ci values->GetValue<int32_t>(value); 61e0e9324cSopenharmony_ci maxContext_ = static_cast<uint32_t>(value); 62e0e9324cSopenharmony_ci } else { 63e0e9324cSopenharmony_ci maxContext_ = MAX_CONTEXT_NUM; 64e0e9324cSopenharmony_ci } 65e0e9324cSopenharmony_ci 66e0e9324cSopenharmony_ci int32_t logOn; 67e0e9324cSopenharmony_ci ret = Config::GetInstance().GetConfig("network", "networkLimit", "logOn", values); 68e0e9324cSopenharmony_ci if (ret == CONFIGURE_ERROR_NONE) { 69e0e9324cSopenharmony_ci values->GetValue<int32_t>(logOn); 70e0e9324cSopenharmony_ci } else { 71e0e9324cSopenharmony_ci logOn = 0; 72e0e9324cSopenharmony_ci } 73e0e9324cSopenharmony_ci 74e0e9324cSopenharmony_ci NetworkSessionManager::GetInstance().SetLogFlag(static_cast<int8_t>(logOn)); 75e0e9324cSopenharmony_ci} 76e0e9324cSopenharmony_ci 77e0e9324cSopenharmony_ciint32_t ContextManager::HandleEvent(SharingEvent &event) 78e0e9324cSopenharmony_ci{ 79e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 80e0e9324cSopenharmony_ci RETURN_INVALID_IF_NULL(event.eventMsg); 81e0e9324cSopenharmony_ci SHARING_LOGI("fromMgr: %{public}u, srcId: %{public}u, toMgr: %{public}u, dstId: %{public}u, event: %{public}s.", 82e0e9324cSopenharmony_ci event.eventMsg->fromMgr, event.eventMsg->srcId, event.eventMsg->toMgr, event.eventMsg->dstId, 83e0e9324cSopenharmony_ci std::string(magic_enum::enum_name(event.eventMsg->type)).c_str()); 84e0e9324cSopenharmony_ci switch (event.eventMsg->type) { 85e0e9324cSopenharmony_ci case EventType::EVENT_CONFIGURE_CONTEXT: 86e0e9324cSopenharmony_ci HandleConfiguration(event); 87e0e9324cSopenharmony_ci break; 88e0e9324cSopenharmony_ci case EventType::EVENT_CONTEXTMGR_CREATE: 89e0e9324cSopenharmony_ci event.eventMsg->dstId = HandleContextCreate(); 90e0e9324cSopenharmony_ci break; 91e0e9324cSopenharmony_ci case EventType::EVENT_CONTEXTMGR_AGENT_CREATE: 92e0e9324cSopenharmony_ci HandleAgentCreate(event); 93e0e9324cSopenharmony_ci break; 94e0e9324cSopenharmony_ci case EventType::EVENT_CONTEXTMGR_STATE_CHANNEL_DESTROY: 95e0e9324cSopenharmony_ci HandleMediachannelDestroy(event); 96e0e9324cSopenharmony_ci break; 97e0e9324cSopenharmony_ci default: 98e0e9324cSopenharmony_ci HandleContextEvent(event); 99e0e9324cSopenharmony_ci break; 100e0e9324cSopenharmony_ci } 101e0e9324cSopenharmony_ci 102e0e9324cSopenharmony_ci return 0; 103e0e9324cSopenharmony_ci} 104e0e9324cSopenharmony_ci 105e0e9324cSopenharmony_civoid ContextManager::HandleConfiguration(SharingEvent &event) 106e0e9324cSopenharmony_ci{ 107e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 108e0e9324cSopenharmony_ci auto eventMsg = ConvertEventMsg<ConfigEventMsg>(event); 109e0e9324cSopenharmony_ci if (eventMsg && eventMsg->data) { 110e0e9324cSopenharmony_ci auto data = eventMsg->data; 111e0e9324cSopenharmony_ci if (data->HasTag("agentLimit")) { 112e0e9324cSopenharmony_ci auto valueTest = data->GetSharingValue("agentLimit", "testdescription"); 113e0e9324cSopenharmony_ci if (valueTest != nullptr && valueTest->IsString()) { 114e0e9324cSopenharmony_ci std::string valueData; 115e0e9324cSopenharmony_ci valueTest->GetValue<std::string>(valueData); 116e0e9324cSopenharmony_ci SHARING_LOGD("sinkLimit: %{public}s.", valueData.c_str()); 117e0e9324cSopenharmony_ci } 118e0e9324cSopenharmony_ci } else if (data->HasTag("networkLimit")) { 119e0e9324cSopenharmony_ci auto logFlag = data->GetSharingValue("networkLimit", "logOn"); 120e0e9324cSopenharmony_ci if (logFlag != nullptr && logFlag->IsInt32()) { 121e0e9324cSopenharmony_ci int32_t valueData = -1; 122e0e9324cSopenharmony_ci if (logFlag->GetValue<int32_t>(valueData)) { 123e0e9324cSopenharmony_ci SHARING_LOGD("logFlag: %{public}d.", valueData); 124e0e9324cSopenharmony_ci NetworkSessionManager::GetInstance().SetLogFlag(valueData); 125e0e9324cSopenharmony_ci } 126e0e9324cSopenharmony_ci } 127e0e9324cSopenharmony_ci } 128e0e9324cSopenharmony_ci } else { 129e0e9324cSopenharmony_ci SHARING_LOGE("msg null."); 130e0e9324cSopenharmony_ci } 131e0e9324cSopenharmony_ci} 132e0e9324cSopenharmony_ci 133e0e9324cSopenharmony_civoid ContextManager::HandleAgentCreate(SharingEvent &event) 134e0e9324cSopenharmony_ci{ 135e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 136e0e9324cSopenharmony_ci RETURN_IF_NULL(event.eventMsg); 137e0e9324cSopenharmony_ci 138e0e9324cSopenharmony_ci auto contextEventMsg = ConvertEventMsg<ContextEventMsg>(event); 139e0e9324cSopenharmony_ci RETURN_IF_NULL(contextEventMsg); 140e0e9324cSopenharmony_ci if (!CheckAgentSize((AgentType)contextEventMsg->agentType)) { 141e0e9324cSopenharmony_ci return; 142e0e9324cSopenharmony_ci } 143e0e9324cSopenharmony_ci 144e0e9324cSopenharmony_ci if (event.eventMsg->dstId == INVALID_ID || GetContextById(event.eventMsg->dstId) == nullptr) { 145e0e9324cSopenharmony_ci event.eventMsg->dstId = HandleContextCreate(); 146e0e9324cSopenharmony_ci } 147e0e9324cSopenharmony_ci 148e0e9324cSopenharmony_ci if (event.eventMsg->dstId == INVALID_ID) { 149e0e9324cSopenharmony_ci SHARING_LOGE("create context error! invalid id."); 150e0e9324cSopenharmony_ci return; 151e0e9324cSopenharmony_ci } 152e0e9324cSopenharmony_ci 153e0e9324cSopenharmony_ci event.eventMsg->type = EVENT_CONTEXT_AGENT_CREATE; 154e0e9324cSopenharmony_ci HandleContextEvent(event); 155e0e9324cSopenharmony_ci} 156e0e9324cSopenharmony_ci 157e0e9324cSopenharmony_cibool ContextManager::CheckAgentSize(AgentType agentType) 158e0e9324cSopenharmony_ci{ 159e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 160e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 161e0e9324cSopenharmony_ci if (agentType == SINK_AGENT) { 162e0e9324cSopenharmony_ci int32_t sinkCount = 0; 163e0e9324cSopenharmony_ci for (auto &item : contexts_) { 164e0e9324cSopenharmony_ci sinkCount += (item.second->GetSinkAgentSize()); 165e0e9324cSopenharmony_ci } 166e0e9324cSopenharmony_ci SHARING_LOGI("now sink agent num: %{public}d.", sinkCount); 167e0e9324cSopenharmony_ci if (sinkCount >= GetAgentSinkLimit()) { 168e0e9324cSopenharmony_ci SHARING_LOGE("check agent size error! limit sink agent size."); 169e0e9324cSopenharmony_ci return false; 170e0e9324cSopenharmony_ci } 171e0e9324cSopenharmony_ci } else { 172e0e9324cSopenharmony_ci int32_t srcCount = 0; 173e0e9324cSopenharmony_ci for (auto &item : contexts_) { 174e0e9324cSopenharmony_ci srcCount += (item.second->GetSrcAgentSize()); 175e0e9324cSopenharmony_ci } 176e0e9324cSopenharmony_ci SHARING_LOGI("now src agent num: %{public}d.", srcCount); 177e0e9324cSopenharmony_ci if (srcCount >= GetAgentSrcLimit()) { 178e0e9324cSopenharmony_ci SHARING_LOGE("check agent size error! limit src agent size."); 179e0e9324cSopenharmony_ci return false; 180e0e9324cSopenharmony_ci } 181e0e9324cSopenharmony_ci } 182e0e9324cSopenharmony_ci 183e0e9324cSopenharmony_ci return true; 184e0e9324cSopenharmony_ci} 185e0e9324cSopenharmony_ci 186e0e9324cSopenharmony_ciuint32_t ContextManager::HandleContextCreate() 187e0e9324cSopenharmony_ci{ 188e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 189e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 190e0e9324cSopenharmony_ci if (contexts_.size() >= maxContext_) { 191e0e9324cSopenharmony_ci SHARING_LOGE("create context error! limit context size."); 192e0e9324cSopenharmony_ci return INVALID_ID; 193e0e9324cSopenharmony_ci } 194e0e9324cSopenharmony_ci 195e0e9324cSopenharmony_ci auto context = std::make_shared<Context>(); 196e0e9324cSopenharmony_ci contexts_.emplace(context->GetId(), context); 197e0e9324cSopenharmony_ci SHARING_LOGI("contextId: %{public}d contextSize: %{public}zu.", context->GetId(), contexts_.size()); 198e0e9324cSopenharmony_ci return context->GetId(); 199e0e9324cSopenharmony_ci} 200e0e9324cSopenharmony_ci 201e0e9324cSopenharmony_civoid ContextManager::HandleMediachannelDestroy(SharingEvent &event) 202e0e9324cSopenharmony_ci{ 203e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 204e0e9324cSopenharmony_ci RETURN_IF_NULL(event.eventMsg); 205e0e9324cSopenharmony_ci auto context = GetContextById(event.eventMsg->dstId); 206e0e9324cSopenharmony_ci if (context) { 207e0e9324cSopenharmony_ci event.eventMsg->type = EVENT_CONTEXT_STATE_AGENT_DESTROY; 208e0e9324cSopenharmony_ci context->HandleEvent(event); 209e0e9324cSopenharmony_ci if (context->IsEmptyAgent()) { 210e0e9324cSopenharmony_ci DestroyContext(event.eventMsg->dstId); 211e0e9324cSopenharmony_ci } else { 212e0e9324cSopenharmony_ci SHARING_LOGD("need wait other agent destroy contextId: %{public}u.", context->GetId()); 213e0e9324cSopenharmony_ci } 214e0e9324cSopenharmony_ci } else { 215e0e9324cSopenharmony_ci SHARING_LOGW("exception to enter! dstId: %{public}u.", event.eventMsg->dstId); 216e0e9324cSopenharmony_ci } 217e0e9324cSopenharmony_ci} 218e0e9324cSopenharmony_ci 219e0e9324cSopenharmony_civoid ContextManager::HandleContextEvent(SharingEvent &event) 220e0e9324cSopenharmony_ci{ 221e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 222e0e9324cSopenharmony_ci RETURN_IF_NULL(event.eventMsg); 223e0e9324cSopenharmony_ci auto context = GetContextById(event.eventMsg->dstId); 224e0e9324cSopenharmony_ci if (context) { 225e0e9324cSopenharmony_ci context->HandleEvent(event); 226e0e9324cSopenharmony_ci } else { 227e0e9324cSopenharmony_ci SHARING_LOGE("context not exist, contextId: %{public}u eventType: %{public}s.", event.eventMsg->dstId, 228e0e9324cSopenharmony_ci std::string(magic_enum::enum_name(event.eventMsg->type)).c_str()); 229e0e9324cSopenharmony_ci } 230e0e9324cSopenharmony_ci} 231e0e9324cSopenharmony_ci 232e0e9324cSopenharmony_ciContext::Ptr ContextManager::GetContextById(uint32_t contextId) 233e0e9324cSopenharmony_ci{ 234e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 235e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 236e0e9324cSopenharmony_ci auto itr = contexts_.find(contextId); 237e0e9324cSopenharmony_ci if (itr != contexts_.end()) { 238e0e9324cSopenharmony_ci return itr->second; 239e0e9324cSopenharmony_ci } 240e0e9324cSopenharmony_ci 241e0e9324cSopenharmony_ci return nullptr; 242e0e9324cSopenharmony_ci} 243e0e9324cSopenharmony_ci 244e0e9324cSopenharmony_civoid ContextManager::DestroyContext(uint32_t contextId) 245e0e9324cSopenharmony_ci{ 246e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 247e0e9324cSopenharmony_ci bool paFlag = false; 248e0e9324cSopenharmony_ci { 249e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 250e0e9324cSopenharmony_ci auto itr = contexts_.find(contextId); 251e0e9324cSopenharmony_ci if (itr != contexts_.end()) { 252e0e9324cSopenharmony_ci if (itr->second != nullptr) { 253e0e9324cSopenharmony_ci itr->second->Release(); 254e0e9324cSopenharmony_ci } 255e0e9324cSopenharmony_ci contexts_.erase(itr); 256e0e9324cSopenharmony_ci } 257e0e9324cSopenharmony_ci if (0 == contexts_.size()) { 258e0e9324cSopenharmony_ci paFlag = true; 259e0e9324cSopenharmony_ci } 260e0e9324cSopenharmony_ci } 261e0e9324cSopenharmony_ci 262e0e9324cSopenharmony_ci if (paFlag) { 263e0e9324cSopenharmony_ci system("pactl set-default-source Built_in_mic"); 264e0e9324cSopenharmony_ci system("pactl set-default-sink Speaker"); 265e0e9324cSopenharmony_ci } 266e0e9324cSopenharmony_ci 267e0e9324cSopenharmony_ci SHARING_LOGI("contextId: %{public}d contextSize: %{public}zu.", contextId, contexts_.size()); 268e0e9324cSopenharmony_ci} 269e0e9324cSopenharmony_ci 270e0e9324cSopenharmony_ci} // namespace Sharing 271e0e9324cSopenharmony_ci} // namespace OHOS