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