• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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